1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

adding OpenCV Manager

This commit is contained in:
Andrey Pavlenko
2012-06-21 14:50:05 +00:00
parent a3be73b5cc
commit 2984fa751e
133 changed files with 34065 additions and 84 deletions
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>OpenCVEngineService</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv.engine"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<service android:exported="true" android:name="OpenCVEngineService" android:process=":OpenCVEngineProcess">
<intent-filter>
<action android:name="org.opencv.engine.BIND"></action>
</intent-filter>
</service>
<activity android:name="org.opencv.engine.manager.ManagerActivity" android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
+37
View File
@@ -0,0 +1,37 @@
set(engine OpenCVEngine)
set(JNI_LIB_NAME ${engine} ${engine}_jni)
add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 8 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON)
link_directories("${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib" "${ANDROID_SOURCE_TREE}/bin_${ANDROID_ARCH_NAME}/system/lib")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-allow-shlib-undefined")
file(GLOB engine_files "jni/BinderComponent/*.cpp" "jni/BinderComponent/*.h" "jni/include/*.h")
include_directories(jni/BinderComponent jni/include "${ANDROID_SOURCE_TREE}/frameworks/base/include" "${ANDROID_SOURCE_TREE}/system/core/include")
add_library(${engine} SHARED ${engine_files})
target_link_libraries(${engine} z binder log utils)
set_target_properties(${engine} PROPERTIES
OUTPUT_NAME ${engine}
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.build/libs/${ANDROID_NDK_ABI_NAME}"
)
get_target_property(engine_lib_location ${engine} LOCATION)
add_custom_command(TARGET ${engine} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${engine_lib_location}")
file(GLOB engine_jni_files "jni/JNIWrapper/*.cpp" "jni/JNIWrapper/*.h" "jni/include/*.h")
list(APPEND engine_jni_files jni/NativeService/CommonPackageManager.cpp jni/NativeService/PackageInfo.cpp)
include_directories(jni/include jni/JNIWrapper jni/NativeService jni/BinderComponent "${ANDROID_SOURCE_TREE}/frameworks/base/include" "${ANDROID_SOURCE_TREE}/system/core/include" "${ANDROID_SOURCE_TREE}/frameworks/base/core/jni")
add_library(${engine}_jni SHARED ${engine_jni_files})
target_link_libraries(${engine}_jni z binder log utils android_runtime ${engine})
set_target_properties(${engine}_jni PROPERTIES
OUTPUT_NAME ${engine}_jni
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.build/libs/${ANDROID_NDK_ABI_NAME}"
)
get_target_property(engine_lib_location ${engine}_jni LOCATION)
add_custom_command(TARGET ${engine}_jni POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${engine_lib_location}")
+78
View File
@@ -0,0 +1,78 @@
LOCAL_PATH := $(call my-dir)
#---------------------------------------------------------------------
# Binder component library
#---------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
BinderComponent/OpenCVEngine.cpp \
BinderComponent/BnOpenCVEngine.cpp \
BinderComponent/BpOpenCVEngine.cpp \
BinderComponent/ProcReader.cpp \
BinderComponent/TegraDetector.cpp \
BinderComponent/StringUtils.cpp \
BinderComponent/HardwareDetector.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/BinderComponent \
$(TOP)/frameworks/base/include \
$(TOP)/system/core/include
LOCAL_CFLAGS += -DPLATFORM_ANDROID
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libOpenCVEngine
LOCAL_LDLIBS += -lz -lbinder -llog -lutils
LOCAL_LDFLAGS += -Wl,-allow-shlib-undefine
include $(BUILD_SHARED_LIBRARY)
#---------------------------------------------------------------------
# JNI library for Java service
#---------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
JNIWrapper/OpenCVEngine_jni.cpp \
NativeService/CommonPackageManager.cpp \
JNIWrapper/JavaBasedPackageManager.cpp \
NativeService/PackageInfo.cpp \
JNIWrapper/HardwareDetector_jni.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/JNIWrapper \
$(LOCAL_PATH)/NativeService \
$(LOCAL_PATH)/BinderComponent \
$(TOP)/frameworks/base/include \
$(TOP)/system/core/include \
$(TOP)/frameworks/base/core/jni
LOCAL_PRELINK_MODULE := false
LOCAL_CFLAGS += -DPLATFORM_ANDROID
LOCAL_MODULE := libOpenCVEngine_jni
LOCAL_LDLIBS += -lz -lbinder -llog -lutils -landroid_runtime
LOCAL_SHARED_LIBRARIES = libOpenCVEngine
include $(BUILD_SHARED_LIBRARY)
#---------------------------------------------------------------------
# Native test application
#---------------------------------------------------------------------
include $(LOCAL_PATH)/Tests/Tests.mk
@@ -0,0 +1,5 @@
APP_ABI := armeabi x86
APP_PLATFORM := android-8
APP_STL := stlport_static
APP_CPPFLAGS := -fno-rtti -fno-exceptions
#APP_OPTIM := debug
@@ -0,0 +1,74 @@
#include "EngineCommon.h"
#include "IOpenCVEngine.h"
#include "BnOpenCVEngine.h"
#include <utils/Log.h>
#include <utils/String8.h>
#include <utils/String16.h>
using namespace android;
BnOpenCVEngine::~BnOpenCVEngine()
{
}
// Notes about data transaction:
// Java Binder Wrapper call readInt32 before reading return data
// It treet this in value as exception code
// OnTransact method support this feature
status_t BnOpenCVEngine::onTransact(uint32_t code, const Parcel& data, android::Parcel* reply, uint32_t flags)
{
LOGD("OpenCVEngine::OnTransact(%u,%u)", code, flags);
switch(code)
{
case OCVE_GET_ENGINE_VERSION:
{
LOGD("OpenCVEngine OCVE_GET_ENGINE_VERSION request");
CHECK_INTERFACE(IOpenCVEngine, data, reply);
LOGD("OpenCVEngine::GetVersion()");
reply->writeInt32(0);
return reply->writeInt32(GetVersion());
} break;
case OCVE_GET_LIB_PATH_BY_VERSION:
{
LOGD("OpenCVEngine OCVE_GET_LIB_PATH_BY_VERSION request");
CHECK_INTERFACE(IOpenCVEngine, data, reply);
const String16 version = data.readString16();
LOGD("OpenCVEngine::GetLibPathByVersion(%s)", String8(version).string());
String16 path = GetLibPathByVersion(version);
reply->writeInt32(0);
return reply->writeString16(path);
} break;
case OCVE_GET_LIB_LIST:
{
LOGD("OpenCVEngine OCVE_GET_LIB_LIST request");
CHECK_INTERFACE(IOpenCVEngine, data, reply);
const String16 version = data.readString16();
LOGD("OpenCVEngine::GetLibraryList(%s)", String8(version).string());
String16 path = GetLibraryList(version);
reply->writeInt32(0);
return reply->writeString16(path);
} break;
case OCVE_INSTALL_VERSION:
{
LOGD("OpenCVEngine OCVE_INSTALL_VERSION request");
CHECK_INTERFACE(IOpenCVEngine, data, reply);
const String16 version = data.readString16();
LOGD("OpenCVEngine::InstallVersion(%s)", String8(version).string());
bool result = InstallVersion(version);
reply->writeInt32(0);
int res = reply->writeInt32(static_cast<int32_t>(result));
LOGD("InstallVersion call to Binder finished with res %d", res);
return res;
} break;
default:
{
LOGD("OpenCVEngine unknown request");
return BBinder::onTransact(code, data, reply, flags);
}
}
return android::NO_ERROR;
}
@@ -0,0 +1,21 @@
#ifndef __BP_OPENCV_ENGINE_H__
#define __BP_OPENCV_ENGINE_H__
#include "EngineCommon.h"
#include "IOpenCVEngine.h"
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String16.h>
class BnOpenCVEngine: public android::BnInterface<IOpenCVEngine>
{
public:
android::status_t onTransact(uint32_t code,
const android::Parcel &data,
android::Parcel *reply,
uint32_t flags);
virtual ~BnOpenCVEngine();
};
#endif
@@ -0,0 +1,71 @@
#include "IOpenCVEngine.h"
#include "BpOpenCVEngine.h"
using namespace android;
BpOpenCVEngine::BpOpenCVEngine(const sp<IBinder>& impl):
BpInterface<IOpenCVEngine>(impl)
{
}
BpOpenCVEngine::~BpOpenCVEngine()
{
}
// Notes about data transaction:
// Java Binder Wrapper call readInt32 before reading return data
// It treet this in value as exception code
// This implementation support this feature
int BpOpenCVEngine::GetVersion()
{
Parcel data, reply;
data.writeInterfaceToken(IOpenCVEngine::descriptor);
remote()->transact(OCVE_GET_ENGINE_VERSION, data, &reply, 0);
// read exception code
reply.readInt32();
return reply.readInt32();
}
String16 BpOpenCVEngine::GetLibPathByVersion(String16 version)
{
Parcel data, reply;
data.writeInterfaceToken(IOpenCVEngine::descriptor);
data.writeString16(version);
remote()->transact(OCVE_GET_LIB_PATH_BY_VERSION, data, &reply, 0);
// read exception code
reply.readInt32();
return reply.readString16();
}
android::String16 BpOpenCVEngine::GetLibraryList(String16 version)
{
Parcel data, reply;
data.writeInterfaceToken(IOpenCVEngine::descriptor);
data.writeString16(version);
remote()->transact(OCVE_GET_LIB_LIST, data, &reply, 0);
// read exception code
reply.readInt32();
return reply.readString16();
}
bool BpOpenCVEngine::InstallVersion(String16 version)
{
Parcel data, reply;
data.writeInterfaceToken(IOpenCVEngine::descriptor);
data.writeString16(version);
remote()->transact(OCVE_INSTALL_VERSION, data, &reply, 0);
// read exception code
reply.readInt32();
return static_cast<bool>(reply.readInt32());
}
IMPLEMENT_META_INTERFACE(OpenCVEngine, OPECV_ENGINE_CLASSNAME)
@@ -0,0 +1,20 @@
#ifndef __BP_OPENCV_ENGINE_H__
#define __BP_OPENCV_ENGINE_H__
#include "IOpenCVEngine.h"
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String16.h>
class BpOpenCVEngine: public android::BpInterface<IOpenCVEngine>
{
public:
BpOpenCVEngine(const android::sp<android::IBinder>& impl);
virtual ~BpOpenCVEngine();
virtual int GetVersion();
virtual android::String16 GetLibPathByVersion(android::String16 version);
virtual android::String16 GetLibraryList(android::String16 version);
virtual bool InstallVersion(android::String16 version);
};
#endif
@@ -0,0 +1,179 @@
#include "HardwareDetector.h"
#include "TegraDetector.h"
#include "ProcReader.h"
#include "EngineCommon.h"
#include "StringUtils.h"
#include <utils/Log.h>
using namespace std;
int GetCpuID()
{
int result = 0;
map<string, string> cpu_info = GetCpuInfo();
map<string, string>::const_iterator it;
#ifdef __i386__
LOGD("Using X86 HW detector");
result |= ARCH_X86;
it = cpu_info.find("flags");
if (cpu_info.end() != it)
{
set<string> features = SplitString(it->second, ' ');
if (features.end() != features.find(CPU_INFO_SSE_STR))
{
result |= FEATURES_HAS_SSE;
}
if (features.end() != features.find(CPU_INFO_SSE2_STR))
{
result |= FEATURES_HAS_SSE2;
}
if (features.end() != features.find(CPU_INFO_SSSE3_STR))
{
result |= FEATURES_HAS_SSSE3;
}
}
#else
LOGD("Using ARM HW detector");
it = cpu_info.find("Processor");
if (cpu_info.end() != it)
{
size_t proc_name_pos = it->second.find(CPU_INFO_ARCH_X86_STR);
if (string::npos != proc_name_pos)
{
}
else
{
proc_name_pos = it->second.find(CPU_INFO_ARCH_ARMV7_STR);
if (string::npos != proc_name_pos)
{
result |= ARCH_ARMv7;
}
else
{
proc_name_pos = it->second.find(CPU_INFO_ARCH_ARMV6_STR);
if (string::npos != proc_name_pos)
{
result |= ARCH_ARMv6;
}
else
{
proc_name_pos = it->second.find(CPU_INFO_ARCH_ARMV5_STR);
if (string::npos != proc_name_pos)
{
result |= ARCH_ARMv5;
}
}
}
}
}
else
{
return ARCH_UNKNOWN;
}
it = cpu_info.find("Features");
if (cpu_info.end() != it)
{
set<string> features = SplitString(it->second, ' ');
if (features.end() != features.find(CPU_INFO_NEON_STR))
{
result |= FEATURES_HAS_NEON;
}
if (features.end() != features.find(CPU_INFO_NEON2_STR))
{
result |= FEATURES_HAS_NEON2;
}
if (features.end() != features.find(CPU_INFO_VFPV3_STR))
{
if (features.end () != features.find(CPU_INFO_VFPV3D16_STR))
{
result |= FEATURES_HAS_VFPv3d16;
}
else
{
result |= FEATURES_HAS_VFPv3;
}
}
}
#endif
return result;
}
string GetPlatformName()
{
map<string, string> cpu_info = GetCpuInfo();
string hardware_name = "";
map<string, string>::const_iterator hw_iterator = cpu_info.find("Hardware");
if (cpu_info.end() != hw_iterator)
{
hardware_name = hw_iterator->second;
}
return hardware_name;
}
int GetProcessorCount()
{
FILE* cpuPossible = fopen("/sys/devices/system/cpu/possible", "r");
if(!cpuPossible)
return 1;
char buf[2000]; //big enough for 1000 CPUs in worst possible configuration
char* pbuf = fgets(buf, sizeof(buf), cpuPossible);
fclose(cpuPossible);
if(!pbuf)
return 1;
//parse string of form "0-1,3,5-7,10,13-15"
int cpusAvailable = 0;
while(*pbuf)
{
const char* pos = pbuf;
bool range = false;
while(*pbuf && *pbuf != ',')
{
if(*pbuf == '-') range = true;
++pbuf;
}
if(*pbuf) *pbuf++ = 0;
if(!range)
++cpusAvailable;
else
{
int rstart = 0, rend = 0;
sscanf(pos, "%d-%d", &rstart, &rend);
cpusAvailable += rend - rstart + 1;
}
}
return cpusAvailable ? cpusAvailable : 1;
}
int DetectKnownPlatforms()
{
int tegra_status = DetectTegra();
if (3 == tegra_status)
{
return PLATFORM_TEGRA3;
}
else
{
return PLATFORM_UNKNOWN;
}
// NOTE: Uncomment when all Tegras will be supported
/*if (tegra_status > 0)
{
return PLATFORM_TEGRA + tegra_status - 1;
}
else
{
return PLATFORM_UNKNOWN;
}*/
}
@@ -0,0 +1,35 @@
#ifndef __HARDWARE_DETECTOR_H__
#define __HARDWARE_DETECTOR_H__
#include <string>
#define ARCH_UNKNOWN 0L
#define ARCH_X86 16777216L
#define ARCH_X64 33554432L
#define ARCH_ARMv5 67108864L
#define ARCH_ARMv6 134217728L
#define ARCH_ARMv7 268435456L
#define ARCH_ARMv8 536870912L
#define FEATURES_HAS_VFPv3d16 1L
#define FEATURES_HAS_VFPv3 2L
#define FEATURES_HAS_NEON 4L
#define FEATURES_HAS_NEON2 8L
#define FEATURES_HAS_SSE 1L
#define FEATURES_HAS_SSE2 2L
#define FEATURES_HAS_SSSE3 4L
#define FEATURES_HAS_GPU 65536L
// TODO: Do not forget to add Platrfom name to PackageInfo::PlatformNameMap
// in method PackageInfo::InitPlatformNameMap()
#define PLATFORM_UNKNOWN 0L
#define PLATFORM_TEGRA 1L
#define PLATFORM_TEGRA2 2L
#define PLATFORM_TEGRA3 3L
int DetectKnownPlatforms();
int GetProcessorCount();
std::string GetPlatformName();
int GetCpuID();
#endif
@@ -0,0 +1,225 @@
#include "EngineCommon.h"
#include "OpenCVEngine.h"
#include "HardwareDetector.h"
#include "StringUtils.h"
#include <utils/Log.h>
#include <assert.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <dlfcn.h>
using namespace android;
const int OpenCVEngine::Platform = DetectKnownPlatforms();
const int OpenCVEngine::CpuID = GetCpuID();
std::set<std::string> OpenCVEngine::InitKnownOpenCVersions()
{
std::set<std::string> result;
result.insert("240");
result.insert("241");
result.insert("242");
return result;
}
const std::set<std::string> OpenCVEngine::KnownVersions = InitKnownOpenCVersions();
bool OpenCVEngine::ValidateVersionString(const std::string& version)
{
return (KnownVersions.find(version) != KnownVersions.end());
}
std::string OpenCVEngine::NormalizeVersionString(std::string version)
{
std::string result = "";
std::string suffix = "";
if (version.empty())
{
return result;
}
if (('a' == version[version.size()-1]) || ('b' == version[version.size()-1]))
{
suffix = version[version.size()-1];
version.erase(version.size()-1);
}
std::vector<std::string> parts = SplitStringVector(version, '.');
if (parts.size() >= 2)
{
if (parts.size() >= 3)
{
result = parts[0] + parts[1] + parts[2] + suffix;
if (!ValidateVersionString(result))
result = "";
}
else
{
result = parts[0] + parts[1] + "0" + suffix;
if (!ValidateVersionString(result))
result = "";
}
}
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());
std::string norm_version;
std::string path;
LOGD("OpenCVEngine::GetLibPathByVersion(%s) impl", String8(version).string());
norm_version = NormalizeVersionString(std_version);
if (!norm_version.empty())
{
path = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID);
if (path.empty())
{
LOGI("Package OpenCV of version %s is not installed. Try to install it :)", norm_version.c_str());
}
else
{
FixPermissions(path);
}
}
else
{
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
}
return String16(path.c_str());
}
android::String16 OpenCVEngine::GetLibraryList(android::String16 version)
{
std::string std_version = String8(version).string();
std::string norm_version;
String16 result;
norm_version = NormalizeVersionString(std_version);
if (!norm_version.empty())
{
std::string tmp = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID);
if (!tmp.empty())
{
tmp += "/libopencvinfo.so";
LOGD("Trying to load info library \"%s\"", tmp.c_str());
void *handle;
char* (*info_func)();
handle = dlopen(tmp.c_str(), RTLD_LAZY);
if (handle)
{
const char *error;
dlerror();
*(void **) (&info_func) = 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 is not installed. Try to install it :)", norm_version.c_str());
}
}
else
{
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
}
return result;
}
bool OpenCVEngine::InstallVersion(android::String16 version)
{
std::string std_version = String8(version).string();
std::string norm_version;
bool result = false;
norm_version = NormalizeVersionString(std_version);
if (!norm_version.empty())
{
LOGD("OpenCVEngine::InstallVersion() begin");
if (!PackageManager->CheckVersionInstalled(norm_version, Platform, CpuID))
{
LOGD("PackageManager->InstallVersion call");
result = PackageManager->InstallVersion(norm_version, Platform, CpuID);
}
else
{
LOGI("Package OpenCV of version %s is already installed. Skiped.", norm_version.c_str());
result = true;
}
}
else
{
LOGE("OpenCV version \"%s\" is not supported", norm_version.c_str());
}
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;
}
@@ -0,0 +1,38 @@
#ifndef __OPEN_CV_ENGINE_H__
#define __OPEN_CV_ENGINE_H__
#include "EngineCommon.h"
#include "IOpenCVEngine.h"
#include "BnOpenCVEngine.h"
#include "IPackageManager.h"
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/String16.h>
#include <string>
#include <set>
class OpenCVEngine: public BnOpenCVEngine
{
public:
OpenCVEngine(IPackageManager* PkgManager);
int32_t GetVersion();
android::String16 GetLibPathByVersion(android::String16 version);
virtual android::String16 GetLibraryList(android::String16 version);
bool InstallVersion(android::String16 version);
protected:
IPackageManager* PackageManager;
static const std::set<std::string> KnownVersions;
OpenCVEngine();
static std::set<std::string> InitKnownOpenCVersions();
bool ValidateVersionString(const std::string& version);
std::string NormalizeVersionString(std::string version);
bool FixPermissions(const std::string& path);
static const int Platform;
static const int CpuID;
};
#endif
@@ -0,0 +1,31 @@
#include "ProcReader.h"
#include "StringUtils.h"
#include <fstream>
using namespace std;
map<string, string> GetCpuInfo()
{
map<string, string> result;
ifstream f;
f.open("/proc/cpuinfo");
if (f.is_open())
{
while (!f.eof())
{
string tmp;
string key;
string value;
getline(f, tmp);
if (ParseString(tmp, key, value))
{
result[key] = value;
}
}
}
f.close();
return result;
}
@@ -0,0 +1,27 @@
#ifndef __PROC_READER_H__
#define __PROC_READER_H__
#include <map>
#include <set>
#include <string>
#define CPU_INFO_NEON_STR "neon"
#define CPU_INFO_NEON2_STR "neon2"
#define CPU_INFO_VFPV3_STR "vfpv3"
#define CPU_INFO_VFPV3D16_STR "vfpv3d16"
#define CPU_INFO_SSE_STR "sse"
#define CPU_INFO_SSE2_STR "sse2"
#define CPU_INFO_SSSE3_STR "ssse3"
#define CPU_INFO_ARCH_ARMV7_STR "ARMv7"
#define CPU_INFO_ARCH_ARMV6_STR "ARMv6"
#define CPU_INFO_ARCH_ARMV5_STR "ARMv5"
#define CPU_INFO_ARCH_X86_STR "x86"
// public part
std::map<std::string, std::string> GetCpuInfo();
#endif
@@ -0,0 +1,93 @@
#include "StringUtils.h"
using namespace std;
bool StripString(string& src)
{
size_t pos = 0;
if (src.empty())
{
return false;
}
while ((pos < src.length()) && (' ' == src[pos])) pos++;
src.erase(0, pos);
pos = 0;
while ((pos < src.length()) && ('\t' == src[pos])) pos++;
src.erase(0, pos);
pos = src.length() - 1;
while (pos && (' ' == src[pos])) pos--;
src.erase(pos+1);
pos = src.length() - 1;
while (pos && ('\t' == src[pos])) pos--;
src.erase(pos+1);
return true;
}
bool ParseString(const string& src, string& key, string& value)
{
if (src.empty())
return false;
// find seporator ":"
size_t seporator_pos = src.find(":");
if (string::npos != seporator_pos)
{
key = src.substr(0, seporator_pos);
StripString(key);
value = src.substr(seporator_pos+1);
StripString(value);
return true;
}
else
{
return false;
}
}
set<string> SplitString(const string& src, const char seporator)
{
set<string> result;
if (!src.empty())
{
size_t seporator_pos;
size_t prev_pos = 0;
do
{
seporator_pos = src.find(seporator, prev_pos);
result.insert(src.substr(prev_pos, seporator_pos - prev_pos));
prev_pos = seporator_pos + 1;
}
while (string::npos != seporator_pos);
}
return result;
}
vector<string> SplitStringVector(const string& src, const char seporator)
{
vector<string> result;
if (!src.empty())
{
size_t seporator_pos;
size_t prev_pos = 0;
do
{
seporator_pos = src.find(seporator, prev_pos);
string tmp = src.substr(prev_pos, seporator_pos - prev_pos);
result.push_back(tmp);
prev_pos = seporator_pos + 1;
}
while (string::npos != seporator_pos);
}
return result;
}
@@ -0,0 +1,13 @@
#ifndef __STRING_UTILS_H__
#define __STRING_UTILS_H__
#include <string>
#include <set>
#include <vector>
bool StripString(std::string& src);
std::set<std::string> SplitString(const std::string& src, const char seporator);
bool ParseString(const std::string& src, std::string& key, std::string& value);
std::vector<std::string> SplitStringVector(const std::string& src, const char seporator);
#endif
@@ -0,0 +1,53 @@
#include "TegraDetector.h"
#include <zlib.h>
#include <string.h>
#define KERNEL_CONFIG "/proc/config.gz"
#define KERNEL_CONFIG_MAX_LINE_WIDTH 512
#define KERNEL_CONFIG_TEGRA_MAGIC "CONFIG_ARCH_TEGRA=y"
#define KERNEL_CONFIG_TEGRA2_MAGIC "CONFIG_ARCH_TEGRA_2x_SOC=y"
#define KERNEL_CONFIG_TEGRA3_MAGIC "CONFIG_ARCH_TEGRA_3x_SOC=y"
#define MAX_DATA_LEN 4096
int DetectTegra()
{
int result = TEGRA_NOT_TEGRA;
gzFile kernelConfig = gzopen(KERNEL_CONFIG, "r");
if (kernelConfig != 0)
{
char tmpbuf[KERNEL_CONFIG_MAX_LINE_WIDTH];
const char *tegra_config = KERNEL_CONFIG_TEGRA_MAGIC;
const char *tegra2_config = KERNEL_CONFIG_TEGRA2_MAGIC;
const char *tegra3_config = KERNEL_CONFIG_TEGRA3_MAGIC;
int len = strlen(tegra_config);
int len2 = strlen(tegra2_config);
int len3 = strlen(tegra3_config);
while (0 != gzgets(kernelConfig, tmpbuf, KERNEL_CONFIG_MAX_LINE_WIDTH))
{
if (0 == strncmp(tmpbuf, tegra_config, len))
{
result = 1;
}
if (0 == strncmp(tmpbuf, tegra2_config, len2))
{
result = 2;
break;
}
if (0 == strncmp(tmpbuf, tegra3_config, len3))
{
result = 3;
break;
}
}
gzclose(kernelConfig);
}
else
{
result = TEGRA_DETECTOR_ERROR;
}
return result;
}
@@ -0,0 +1,9 @@
#ifndef __TEGRA_DETECTOR_H__
#define __TEGRA_DETECTOR_H__
#define TEGRA_DETECTOR_ERROR -2
#define TEGRA_NOT_TEGRA -1
int DetectTegra();
#endif
@@ -0,0 +1,25 @@
#include "HardwareDetector_jni.h"
#include "HardwareDetector.h"
#include <jni.h>
#include <string>
JNIEXPORT jint JNICALL Java_org_opencv_engine_manager_HardwareDetector_GetCpuID(JNIEnv* env, jclass)
{
return GetCpuID();
}
JNIEXPORT jstring JNICALL Java_org_opencv_engine_manager_HardwareDetector_GetPlatformName(JNIEnv* env, jclass)
{
std::string hardware_name = GetPlatformName();
return env->NewStringUTF(hardware_name.c_str());
}
JNIEXPORT jint JNICALL Java_org_opencv_engine_manager_HardwareDetector_GetProcessorCount(JNIEnv* env, jclass)
{
return GetProcessorCount();
}
JNIEXPORT jint JNICALL Java_org_opencv_engine_manager_HardwareDetector_DetectKnownPlatforms(JNIEnv* env, jclass)
{
return DetectKnownPlatforms();
}
@@ -0,0 +1,48 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HardwareDetector */
#ifndef _Included_HardwareDetector
#define _Included_HardwareDetector
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_opencv_engine_manager_HardwareDetector
* Method: GetCpuID
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_opencv_engine_manager_HardwareDetector_GetCpuID
(JNIEnv *, jclass);
/*
* Class: org_opencv_engine_manager_HardwareDetector
* Method: GetPlatformName
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_opencv_engine_manager_HardwareDetector_GetPlatformName
(JNIEnv *, jclass);
/*
* Class: org_opencv_engine_manager_HardwareDetector
* Method: GetProcessorCount
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_opencv_engine_manager_HardwareDetector_GetProcessorCount
(JNIEnv *, jclass);
/*
* Class: org_opencv_engine_manager_HardwareDetector
* Method: DetectKnownPlatforms
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_opencv_engine_manager_HardwareDetector_DetectKnownPlatforms
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,176 @@
#include "JavaBasedPackageManager.h"
#include <utils/Log.h>
#include <assert.h>
#undef LOG_TAG
#define LOG_TAG "JavaBasedPackageManager"
using namespace std;
JavaBasedPackageManager::JavaBasedPackageManager(JavaVM* JavaMashine, jobject MarketConnector):
JavaContext(JavaMashine),
JavaPackageManager(MarketConnector)
{
assert(JavaContext);
assert(JavaPackageManager);
}
bool JavaBasedPackageManager::InstallPackage(const PackageInfo& package)
{
JNIEnv* jenv;
bool self_attached;
LOGD("JavaBasedPackageManager::InstallPackage() begin\n");
self_attached = (JNI_EDETACHED == JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6));
if (self_attached)
{
JavaContext->AttachCurrentThread(&jenv, NULL);
}
LOGD("GetObjectClass call\n");
jclass jclazz = jenv->GetObjectClass(JavaPackageManager);
if (!jclazz)
{
LOGE("MarketConnector class was not found!");
return false;
}
LOGD("GetMethodID call\n");
jmethodID jmethod = jenv->GetMethodID(jclazz, "InstallAppFromMarket", "(Ljava/lang/String;)Z");
if (!jmethod)
{
LOGE("MarketConnector::GetAppFormMarket method was not found!");
return false;
}
LOGD("Calling java package manager with package name %s\n", package.GetFullName().c_str());
jobject jpkgname = jenv->NewStringUTF(package.GetFullName().c_str());
bool result = jenv->CallNonvirtualBooleanMethod(JavaPackageManager, jclazz, jmethod, jpkgname);
if (self_attached)
{
JavaContext->DetachCurrentThread();
}
LOGD("JavaBasedPackageManager::InstallPackage() end\n");
return result;
}
vector<PackageInfo> JavaBasedPackageManager::GetInstalledPackages()
{
vector<PackageInfo> result;
JNIEnv* jenv;
bool self_attached;
LOGD("JavaBasedPackageManager::GetInstalledPackages() begin");
self_attached = (JNI_EDETACHED == JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6));
if (self_attached)
{
JavaContext->AttachCurrentThread(&jenv, NULL);
}
LOGD("GetObjectClass call");
jclass jclazz = jenv->GetObjectClass(JavaPackageManager);
if (!jclazz)
{
LOGE("MarketConnector class was not found!");
return result;
}
LOGD("GetMethodID call");
jmethodID jmethod = jenv->GetMethodID(jclazz, "GetInstalledOpenCVPackages", "()[Landroid/content/pm/PackageInfo;");
if (!jmethod)
{
LOGE("MarketConnector::GetInstalledOpenCVPackages method was not found!");
return result;
}
LOGD("Java package manager call");
jobjectArray jpkgs = static_cast<jobjectArray>(jenv->CallNonvirtualObjectMethod(JavaPackageManager, jclazz, jmethod));
jsize size = jenv->GetArrayLength(jpkgs);
LOGD("Package info conversion");
result.reserve(size);
for (jsize i = 0; i < size; i++)
{
jobject jtmp = jenv->GetObjectArrayElement(jpkgs, i);
PackageInfo tmp = ConvertPackageFromJava(jtmp, jenv);
if (tmp.IsValid())
result.push_back(tmp);
}
if (self_attached)
{
JavaContext->DetachCurrentThread();
}
LOGD("JavaBasedPackageManager::GetInstalledPackages() end");
return result;
}
PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNIEnv* jenv)
{
jclass jclazz = jenv->GetObjectClass(package);
jfieldID jfield = jenv->GetFieldID(jclazz, "packageName", "Ljava/lang/String;");
jstring jnameobj = static_cast<jstring>(jenv->GetObjectField(package, jfield));
const char* jnamestr = jenv->GetStringUTFChars(jnameobj, NULL);
string name(jnamestr);
jfield = jenv->GetFieldID(jclazz, "versionName", "Ljava/lang/String;");
jstring jversionobj = static_cast<jstring>(jenv->GetObjectField(package, jfield));
const char* jversionstr = jenv->GetStringUTFChars(jversionobj, NULL);
string verison(jversionstr);
string path;
jclazz = jenv->FindClass("android/os/Build$VERSION");
jfield = jenv->GetStaticFieldID(jclazz, "SDK_INT", "I");
jint api_level = jenv->GetStaticIntField(jclazz, jfield);
if (api_level > 8)
{
jclazz = jenv->GetObjectClass(package);
jfield = jenv->GetFieldID(jclazz, "applicationInfo", "Landroid/content/pm/ApplicationInfo;");
jobject japp_info = jenv->GetObjectField(package, jfield);
jclazz = jenv->GetObjectClass(japp_info);
jfield = jenv->GetFieldID(jclazz, "nativeLibraryDir", "Ljava/lang/String;");
jstring jpathobj = static_cast<jstring>(jenv->GetObjectField(japp_info, jfield));
const char* jpathstr = jenv->GetStringUTFChars(jpathobj, NULL);
path = string(jpathstr);
jenv->ReleaseStringUTFChars(jpathobj, jpathstr);
}
else
{
path = "/data/data/" + name + "/lib";
}
return PackageInfo(name, path, verison);
}
JavaBasedPackageManager::~JavaBasedPackageManager()
{
JNIEnv* jenv;
bool self_attached;
LOGD("JavaBasedPackageManager::~JavaBasedPackageManager() begin");
JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6);
self_attached = (JNI_EDETACHED == JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6));
if (self_attached)
{
JavaContext->AttachCurrentThread(&jenv, NULL);
}
jenv->DeleteGlobalRef(JavaPackageManager);
if (self_attached)
{
JavaContext->DetachCurrentThread();
}
LOGD("JavaBasedPackageManager::~JavaBasedPackageManager() end");
}
@@ -0,0 +1,22 @@
#include "IPackageManager.h"
#include "CommonPackageManager.h"
#include <jni.h>
#include <vector>
class JavaBasedPackageManager: public CommonPackageManager
{
public:
JavaBasedPackageManager(JavaVM* JavaMashine, jobject MarketConector);
virtual ~JavaBasedPackageManager();
protected:
virtual bool InstallPackage(const PackageInfo& package);
virtual std::vector<PackageInfo> GetInstalledPackages();
private:
JavaVM* JavaContext;
jobject JavaPackageManager;
JavaBasedPackageManager();
PackageInfo ConvertPackageFromJava(jobject package, JNIEnv* jenv);
};
@@ -0,0 +1,70 @@
#include "OpenCVEngine_jni.h"
#include "EngineCommon.h"
#include "IOpenCVEngine.h"
#include "OpenCVEngine.h"
#include "IPackageManager.h"
#include "JavaBasedPackageManager.h"
#include <utils/Log.h>
#include <android_util_Binder.h>
#undef LOG_TAG
#define LOG_TAG "OpenCVEngine/JNI"
using namespace android;
sp<IBinder> OpenCVEngineBinder = NULL;
IPackageManager* PackageManager = NULL;
JNIEXPORT jobject JNICALL Java_org_opencv_engine_BinderConnector_Connect(JNIEnv* env, jobject)
{
LOGI("Creating new component");
if (NULL != OpenCVEngineBinder.get())
{
LOGI("New component created successfully");
}
else
{
LOGE("OpenCV Engine component was not created!");
}
return javaObjectForIBinder(env, OpenCVEngineBinder);
}
JNIEXPORT jboolean JNICALL Java_org_opencv_engine_BinderConnector_Init(JNIEnv* env, jobject thiz, jobject market)
{
LOGD("Java_org_opencv_engine_BinderConnector_Init");
if (NULL == PackageManager)
{
JavaVM* jvm;
env->GetJavaVM(&jvm);;
PackageManager = new JavaBasedPackageManager(jvm, env->NewGlobalRef(market));
}
if (PackageManager)
{
if (!OpenCVEngineBinder.get())
{
OpenCVEngineBinder = new OpenCVEngine(PackageManager);
return (NULL != OpenCVEngineBinder.get());
}
else
{
return true;
}
}
else
{
return false;
}
}
JNIEXPORT void JNICALL Java_org_opencv_engine_BinderConnector_Final(JNIEnv *, jobject)
{
LOGD("Java_org_opencv_engine_BinderConnector_Final");
OpenCVEngineBinder = NULL;
delete PackageManager;
PackageManager = NULL;
}
@@ -0,0 +1,37 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_opencv_engine_BinderConnector */
#ifndef _Included_org_opencv_engine_BinderConnector
#define _Included_org_opencv_engine_BinderConnector
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_opencv_engine_BinderConnector
* Method: Connect
* Signature: ()Landroid/os/IBinder;
*/
JNIEXPORT jobject JNICALL Java_org_opencv_engine_BinderConnector_Connect
(JNIEnv *, jobject);
/*
* Class: org_opencv_engine_BinderConnector
* Method: Init
* Signature: (Lorg/opencv/engine/MarketConnector;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_opencv_engine_BinderConnector_Init
(JNIEnv *, jobject, jobject);
/*
* Class: org_opencv_engine_BinderConnector
* Method: Final
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_opencv_engine_BinderConnector_Final
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,42 @@
#include "EngineCommon.h"
#include "IOpenCVEngine.h"
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
#include <stdio.h>
using namespace android;
int main(int argc, char *argv[])
{
LOGI("OpenCVEngine client is now starting");
sp<IServiceManager> ServiceManager = defaultServiceManager();
sp<IBinder> EngineService;
sp<IOpenCVEngine> Engine;
LOGI("Trying to contect to service");
do {
EngineService = ServiceManager->getService(IOpenCVEngine::descriptor);
if (EngineService != 0) break;
LOGW("OpenCVEngine not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
LOGI("Connection established");
Engine = interface_cast<IOpenCVEngine>(EngineService);
int32_t EngineVersion = Engine->GetVersion();
printf("OpenCVEngine version %d started", EngineVersion);
return 0;
}
@@ -0,0 +1,186 @@
#include "IOpenCVEngine.h"
#include "CommonPackageManager.h"
#include "HardwareDetector.h"
#include <utils/Log.h>
#include <algorithm>
#include <stdio.h>
#include <assert.h>
#undef LOG_TAG
#define LOG_TAG "CommonPackageManager"
using namespace std;
set<string> CommonPackageManager::GetInstalledVersions()
{
set<string> result;
vector<PackageInfo> installed_packages = GetInstalledPackages();
for (vector<PackageInfo>::const_iterator it = installed_packages.begin(); it != installed_packages.end(); ++it)
{
string version = it->GetVersion();
assert(!version.empty());
result.insert(version);
}
return result;
}
bool CommonPackageManager::CheckVersionInstalled(const std::string& version, int platform, int cpu_id)
{
bool result = false;
LOGD("CommonPackageManager::CheckVersionInstalled() begin");
PackageInfo target_package(version, platform, cpu_id);
LOGD("GetInstalledPackages() call");
vector<PackageInfo> packages = GetInstalledPackages();
for (vector<PackageInfo>::const_iterator it = packages.begin(); it != packages.end(); ++it)
{
LOGD("Found package: \"%s\"", it->GetFullName().c_str());
}
if (!packages.empty())
{
result = (packages.end() != find(packages.begin(), packages.end(), target_package));
}
LOGD("CommonPackageManager::CheckVersionInstalled() end");
return result;
}
bool CommonPackageManager::InstallVersion(const std::string& version, int platform, int cpu_id)
{
LOGD("CommonPackageManager::InstallVersion() begin");
PackageInfo package(version, platform, cpu_id);
return InstallPackage(package);
}
string CommonPackageManager::GetPackagePathByVersion(const std::string& version, int platform, int cpu_id)
{
string result;
PackageInfo target_package(version, platform, cpu_id);
vector<PackageInfo> all_packages = GetInstalledPackages();
vector<PackageInfo> packages;
for (vector<PackageInfo>::iterator it = all_packages.begin(); it != all_packages.end(); ++it)
{
if (IsVersionCompatible(version, it->GetVersion()))
{
packages.push_back(*it);
}
}
if (!packages.empty())
{
vector<PackageInfo>::iterator found = find(packages.begin(), packages.end(), target_package);
if (packages.end() != found)
{
result = found->GetInstalationPath();
}
else
{
int OptRating = -1;
std::vector<std::pair<int, int> >& group = CommonPackageManager::ArmRating;
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64))
group = CommonPackageManager::IntelRating;
int HardwareRating = GetHardwareRating(platform, cpu_id, group);
if (-1 == HardwareRating)
{
LOGE("Cannot calculate rating for current hardware platfrom!");
}
else
{
for (vector<PackageInfo>::iterator it = packages.begin(); it != packages.end(); ++it)
{
int PackageRating = GetHardwareRating(it->GetPlatform(), it->GetCpuID(), group);
if (PackageRating >= 0)
{
if ((PackageRating <= HardwareRating) && (PackageRating > OptRating))
{
OptRating = PackageRating;
found = it;
}
}
}
if ((-1 != OptRating) && (packages.end() != found))
{
result = found->GetInstalationPath();
}
}
}
}
return result;
}
bool CommonPackageManager::IsVersionCompatible(const std::string& target_version, const std::string& package_version)
{
assert (target_version.size() == 3);
assert (package_version.size() == 3);
bool result = false;
// major version is the same and minor package version is above or the same as target.
if ((package_version[0] == target_version[0]) && (package_version[1] == target_version[1]) && (package_version[2] >= target_version[2]))
{
result = true;
}
return result;
}
int CommonPackageManager::GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group)
{
int result = -1;
for (size_t i = 0; i < group.size(); i++)
{
if (group[i] == std::pair<int, int>(platform, cpu_id))
{
result = i;
break;
}
}
return result;
}
std::vector<std::pair<int, int> > CommonPackageManager::InitArmRating()
{
std::vector<std::pair<int, int> > result;
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv5));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3d16));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON));
result.push_back(std::pair<int, int>(PLATFORM_TEGRA2, ARCH_ARMv7 | FEATURES_HAS_VFPv3));
result.push_back(std::pair<int, int>(PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON));
return result;
}
std::vector<std::pair<int, int> > CommonPackageManager::InitIntelRating()
{
std::vector<std::pair<int, int> > result;
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X64));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSSE3));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE));
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_X86));
return result;
}
std::vector<std::pair<int, int> > CommonPackageManager::IntelRating = CommonPackageManager::InitIntelRating();
std::vector<std::pair<int, int> > CommonPackageManager::ArmRating = InitArmRating();
CommonPackageManager::~CommonPackageManager()
{
}
@@ -0,0 +1,34 @@
#ifndef __COMMON_PACKAGE_MANAGER_H__
#define __COMMON_PACKAGE_MANAGER_H__
#include "IPackageManager.h"
#include "PackageInfo.h"
#include <set>
#include <vector>
#include <string>
class CommonPackageManager: public IPackageManager
{
public:
std::set<std::string> GetInstalledVersions();
bool CheckVersionInstalled(const std::string& version, int platform, int cpu_id);
bool InstallVersion(const std::string& version, int platform, int cpu_id);
std::string GetPackagePathByVersion(const std::string& version, int platform, int cpu_id);
virtual ~CommonPackageManager();
protected:
static std::vector<std::pair<int, int> > ArmRating;
static std::vector<std::pair<int, int> > IntelRating;
static std::vector<std::pair<int, int> > InitArmRating();
static std::vector<std::pair<int, int> > InitIntelRating();
bool IsVersionCompatible(const std::string& target_version, const std::string& package_version);
int GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group);
virtual bool InstallPackage(const PackageInfo& package) = 0;
virtual std::vector<PackageInfo> GetInstalledPackages() = 0;
};
#endif
@@ -0,0 +1,19 @@
#include "NativePackageManager.h"
using namespace std;
bool NativePackageManager::InstallPackage(const PackageInfo& package)
{
return false;
}
vector<PackageInfo> NativePackageManager::GetInstalledPackages()
{
vector<PackageInfo> result;
return result;
}
NativePackageManager::~NativePackageManager()
{
}
@@ -0,0 +1,16 @@
#ifndef __NATIVE_PACKAGE_MANAGER_STUB_H__
#define __NATIVE_PACKAGE_MANAGER_STUB_H__
#include "IPackageManager.h"
#include "CommonPackageManager.h"
class NativePackageManager: public CommonPackageManager
{
public:
virtual ~NativePackageManager();
protected:
virtual bool InstallPackage(const PackageInfo& package);
virtual std::vector<PackageInfo> GetInstalledPackages();
};
#endif
@@ -0,0 +1,391 @@
#include "EngineCommon.h"
#include "PackageInfo.h"
#include "HardwareDetector.h"
#include "IOpenCVEngine.h"
#include "StringUtils.h"
#include <assert.h>
#include <vector>
#include <utils/Log.h>
using namespace std;
map<int, string> PackageInfo::InitPlatformNameMap()
{
map<int, string> result;
// TODO: Do not forget to add Platrfom constant to HardwareDetector.h
result[PLATFORM_TEGRA] = PLATFORM_TEGRA_NAME;
result[PLATFORM_TEGRA2] = PLATFORM_TEGRA2_NAME;
result[PLATFORM_TEGRA3] = PLATFORM_TEGRA3_NAME;
return result;
}
const map<int, string> PackageInfo::PlatformNameMap = InitPlatformNameMap();
const string PackageInfo::BasePackageName = "org.opencv.lib";
inline string JoinARMFeatures(int cpu_id)
{
string result;
if (FEATURES_HAS_NEON2 & cpu_id)
{
result = string(FEATURES_HAS_NEON2_NAME);
}
else if (FEATURES_HAS_NEON & cpu_id)
{
result = string(FEATURES_HAS_NEON_NAME);
}
else if (FEATURES_HAS_VFPv3 & cpu_id)
{
result = string(FEATURES_HAS_VFPv3_NAME);
}
else if (FEATURES_HAS_VFPv3d16 & cpu_id)
{
result = string(FEATURES_HAS_VFPv3d16_NAME);
}
return result;
}
inline int SplitARMFeatures(const vector<string>& features)
{
int result = 0;
for (size_t i = 3; i < features.size(); i++)
{
if (FEATURES_HAS_VFPv3_NAME == features[i])
{
result |= FEATURES_HAS_VFPv3;
}
else if (FEATURES_HAS_VFPv3d16_NAME == features[i])
{
result |= FEATURES_HAS_VFPv3d16;
}
else if (FEATURES_HAS_NEON_NAME == features[i])
{
result |= FEATURES_HAS_NEON;
}
else if (FEATURES_HAS_NEON2_NAME == features[i])
{
result |= FEATURES_HAS_NEON2;
}
}
return result;
}
inline string JoinIntelFeatures(int cpu_id)
{
string result;
if (FEATURES_HAS_SSSE3 & cpu_id)
{
result = FEATURES_HAS_SSSE3_NAME;
}
else if (FEATURES_HAS_SSE2 & cpu_id)
{
result = FEATURES_HAS_SSE2_NAME;
}
else if (FEATURES_HAS_SSE & cpu_id)
{
result = FEATURES_HAS_SSE_NAME;
}
return result;
}
inline int SplitIntelFeatures(const vector<string>& features)
{
int result = 0;
for (size_t i = 3; i < features.size(); i++)
{
if (FEATURES_HAS_SSSE3_NAME == features[i])
{
result |= FEATURES_HAS_SSSE3;
}
else if (FEATURES_HAS_SSE2_NAME == features[i])
{
result |= FEATURES_HAS_SSE2;
}
else if (FEATURES_HAS_SSE_NAME == features[i])
{
result |= FEATURES_HAS_SSE;
}
}
return result;
}
inline string SplitVersion(const vector<string>& features, const string& package_version)
{
string result;
if ((features.size() > 1) && ('v' == features[1][0]))
{
result = features[1].substr(1);
result += SplitStringVector(package_version, '.')[0];
}
else
{
// TODO: Report package name format error
}
return result;
}
inline string JoinPlatform(int platform)
{
string result;
map<int, string>::const_iterator it = PackageInfo::PlatformNameMap.find(platform);
assert(PackageInfo::PlatformNameMap.end() != it);
result = it->second;
return result;
}
inline int SplitPlatfrom(const vector<string>& features)
{
int result = 0;
if (features.size() > 2)
{
string tmp = features[2];
if (PLATFORM_TEGRA_NAME == tmp)
{
result = PLATFORM_TEGRA;
}
else if (PLATFORM_TEGRA2_NAME == tmp)
{
result = PLATFORM_TEGRA2;
}
else if (PLATFORM_TEGRA3_NAME == tmp)
{
result = PLATFORM_TEGRA3;
}
}
else
{
// TODO: Report package name format error
}
return result;
}
/* Package naming convention
* All parts of package name seporated by "_" symbol
* First part is base namespace.
* Second part is version. Version starts from "v" symbol. After "v" symbol version nomber without dot symbol added.
* If platform is known third part is platform name
* If platform is unknown it is defined by hardware capabilities using pattern: <arch>_<fpu features>_<vectorisation features>_<other features>
* Example: armv7_vfpv3_neon, armv7_vfpv3d16_neon
*/
PackageInfo::PackageInfo(const string& version, int platform, int cpu_id):
Version(version),
Platform(platform),
CpuID(cpu_id),
InstallPath("")
{
FullName = BasePackageName + "_v" + Version.substr(0, Version.size()-1);
if (PLATFORM_UNKNOWN != Platform)
{
FullName += string("_") + JoinPlatform(platform);
}
else
{
if (ARCH_UNKNOWN != CpuID)
{
if (ARCH_X86 & CpuID)
{
LOGD("Found processor with x86 arch");
FullName += string("_") + ARCH_X86_NAME;
// NOTE: Intel features temporary are not supported
//string features = JoinIntelFeatures(CpuID);
string features;
if (!features.empty())
{
FullName += string("_") + features;
}
}
if (ARCH_X64 & CpuID)
{
LOGD("Found processor with x64 arch");
// NOTE: Intel features temporary are not supported
//FullName += string("_") + ARCH_X64_NAME;
//string features = JoinIntelFeatures(CpuID);
FullName += string("_") + ARCH_X86_NAME;
string features;
if (!features.empty())
{
FullName += string("_") + features;
}
}
if (ARCH_ARMv5 & CpuID)
{
LOGD("Found processor with ARMv5 arch");
FullName += string("_") + ARCH_ARMv5_NAME;
string features = JoinARMFeatures(CpuID);
if (!features.empty())
{
FullName += string("_") + features;
}
}
if (ARCH_ARMv6 & CpuID)
{
LOGD("Found processor with ARMv6 arch");
// NOTE: ARM v6 used instead ARM v6
//FullName += string("_") + ARCH_ARMv6_NAME;
FullName += string("_") + ARCH_ARMv5_NAME;
// NOTE: ARM features temporary are not supported
//string features = JoinARMFeatures(CpuID);
string features;
if (!features.empty())
{
FullName += string("_") + features;
}
}
if (ARCH_ARMv7 & CpuID)
{
LOGD("Found processor with ARMv7 arch");
FullName += string("_") + ARCH_ARMv7_NAME;
// NOTE: ARM features temporary are not supported
//string features = JoinARMFeatures(CpuID);
string features;
if (!features.empty())
{
FullName += string("_") + features;
}
}
if (ARCH_ARMv8 & CpuID)
{
LOGD("Found processor with ARMv8 arch");
FullName += string("_") + ARCH_ARMv8_NAME;
string features = JoinARMFeatures(CpuID);
if (!features.empty())
{
FullName += string("_") + features;
}
}
}
else
{
LOGD("Found processor with unknown arch");
Version.clear();
CpuID = ARCH_UNKNOWN;
Platform = PLATFORM_UNKNOWN;
}
}
}
PackageInfo::PackageInfo(const string& fullname, const string& install_path, const string& package_version):
FullName(fullname),
InstallPath(install_path)
{
LOGD("PackageInfo::PackageInfo(\"%s\", \"%s\")", fullname.c_str(), install_path.c_str());
assert(!fullname.empty());
assert(!install_path.empty());
vector<string> features = SplitStringVector(FullName, '_');
if (!features.empty() && (BasePackageName == features[0]))
{
Version = SplitVersion(features, package_version);
if (Version.empty())
{
CpuID = ARCH_UNKNOWN;
Platform = PLATFORM_UNKNOWN;
return;
}
Platform = SplitPlatfrom(features);
if (PLATFORM_UNKNOWN != Platform)
{
CpuID = 0;
}
else
{
if (features.size() < 3)
{
LOGD("It is not OpenCV library package for this platform");
Version.clear();
CpuID = ARCH_UNKNOWN;
Platform = PLATFORM_UNKNOWN;
return;
}
else if (ARCH_ARMv5_NAME == features[2])
{
CpuID = ARCH_ARMv5 | SplitARMFeatures(features);
}
else if (ARCH_ARMv6_NAME == features[2])
{
CpuID = ARCH_ARMv6 | SplitARMFeatures(features);
}
else if (ARCH_ARMv7_NAME == features[2])
{
CpuID = ARCH_ARMv7 | SplitARMFeatures(features);
}
else if (ARCH_X86_NAME == features[2])
{
CpuID = ARCH_X86 | SplitIntelFeatures(features);
}
else if (ARCH_X64_NAME == features[2])
{
CpuID = ARCH_X64 | SplitIntelFeatures(features);
}
else
{
LOGD("It is not OpenCV library package for this platform");
Version.clear();
CpuID = ARCH_UNKNOWN;
Platform = PLATFORM_UNKNOWN;
return;
}
}
}
else
{
LOGD("It is not OpenCV library package for this platform");
Version.clear();
CpuID = ARCH_UNKNOWN;
Platform = PLATFORM_UNKNOWN;
return;
}
}
bool PackageInfo::IsValid() const
{
return !(Version.empty() && (PLATFORM_UNKNOWN == Platform) && (ARCH_UNKNOWN == CpuID));
}
int PackageInfo::GetPlatform() const
{
return Platform;
}
int PackageInfo::GetCpuID() const
{
return CpuID;
}
string PackageInfo::GetFullName() const
{
return FullName;
}
string PackageInfo::GetVersion() const
{
return Version;
}
string PackageInfo::GetInstalationPath() const
{
return InstallPath;
}
bool PackageInfo::operator==(const PackageInfo& package) const
{
return (package.FullName == FullName);
}
@@ -0,0 +1,52 @@
#ifndef __PACKAGE_INFO_H__
#define __PACKAGE_INFO_H__
#include <map>
#include <string>
#define ARCH_X86_NAME "x86"
#define ARCH_X64_NAME "x64"
#define ARCH_ARMv5_NAME "armv5"
#define ARCH_ARMv6_NAME "armv6"
#define ARCH_ARMv7_NAME "armv7"
#define ARCH_ARMv8_NAME "armv8"
#define FEATURES_HAS_VFPv3d16_NAME "vfpv3d16"
#define FEATURES_HAS_VFPv3_NAME "vfpv3"
#define FEATURES_HAS_NEON_NAME "neon"
#define FEATURES_HAS_NEON2_NAME "neon2"
#define FEATURES_HAS_SSE_NAME "sse"
#define FEATURES_HAS_SSE2_NAME "sse2"
#define FEATURES_HAS_SSSE3_NAME "ssse3"
#define FEATURES_HAS_GPU_NAME "gpu"
#define PLATFORM_TEGRA_NAME "tegra"
#define PLATFORM_TEGRA2_NAME "tegra2"
#define PLATFORM_TEGRA3_NAME "tegra3"
class PackageInfo
{
public:
PackageInfo(const std::string& version, int platform, int cpu_id);
PackageInfo(const std::string& fullname, const std::string& install_path, const std::string& package_version = "0.0");
std::string GetFullName() const;
std::string GetVersion() const;
int GetPlatform() const;
int GetCpuID() const;
std::string GetInstalationPath() const;
bool operator==(const PackageInfo& package) const;
static const std::map<int, std::string> PlatformNameMap;
bool IsValid() const;
protected:
static std::map<int, std::string> InitPlatformNameMap();
std::string Version;
int Platform;
int CpuID;
std::string FullName;
std::string InstallPath;
static const std::string BasePackageName;
};
#endif
@@ -0,0 +1,32 @@
#include "EngineCommon.h"
#include "IOpenCVEngine.h"
#include "OpenCVEngine.h"
#include "IPackageManager.h"
#include "NativePackageManager.h"
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
using namespace android;
int main(int argc, char *argv[])
{
LOGI("OpenCVEngine native service starting");
IPackageManager* PackageManager = new NativePackageManager();
sp<IBinder> Engine = new OpenCVEngine(PackageManager);
defaultServiceManager()->addService(IOpenCVEngine::descriptor, Engine);
LOGI("OpenCVEngine native service started successfully");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("OpenCVEngine native service finished");
delete PackageManager;
return 0;
}
@@ -0,0 +1,155 @@
#include <gtest/gtest.h>
#include "ProcReader.h"
#include "TegraDetector.h"
#include "HardwareDetector.h"
#include "StringUtils.h"
using namespace std;
TEST(Strip, StripEmptyString)
{
string a = "";
EXPECT_FALSE(StripString(a));
}
TEST(Strip, StripClearString)
{
string a = "qqqwww";
EXPECT_TRUE(StripString(a));
EXPECT_STREQ("qqqwww", a.c_str());
}
TEST(Strip, StripStringLeft)
{
string a = " qqqwww";
EXPECT_TRUE(StripString(a));
EXPECT_STREQ("qqqwww", a.c_str());
}
TEST(Strip, StripStringRight)
{
string a = "qqqwww ";
EXPECT_TRUE(StripString(a));
EXPECT_STREQ("qqqwww", a.c_str());
}
TEST(Strip, StripStringLeftRight)
{
string a = "qqqwww ";
EXPECT_TRUE(StripString(a));
EXPECT_STREQ("qqqwww", a.c_str());
}
TEST(Strip, StripStringWithSpaces)
{
string a = " qqq www ";
EXPECT_TRUE(StripString(a));
EXPECT_STREQ("qqq www", a.c_str());
}
TEST(Parse, ParseEmptyString)
{
string a = "";
string key;
string value;
EXPECT_FALSE(ParseString(a, key, value));
}
TEST(Parse, ParseStringWithoutSeporator)
{
string a = "qqqwww";
string key;
string value;
EXPECT_FALSE(ParseString(a, key, value));
}
TEST(Parse, ParseClearString)
{
string a = "qqq:www";
string key;
string value;
EXPECT_TRUE(ParseString(a, key, value));
EXPECT_STREQ("qqq", key.c_str());
EXPECT_STREQ("www", value.c_str());
}
TEST(Parse, ParseDirtyString)
{
string a = "qqq : www";
string key;
string value;
EXPECT_TRUE(ParseString(a, key, value));
EXPECT_STREQ("qqq", key.c_str());
EXPECT_STREQ("www", value.c_str());
}
TEST(Split, SplitEmptyString)
{
string a = "";
set<string> b = SplitString(a, ' ');
EXPECT_EQ(0, b.size());
}
TEST(Split, SplitOneElementString)
{
string a = "qqq";
set<string> b = SplitString(a, ' ');
EXPECT_EQ(1, b.size());
EXPECT_FALSE(b.find("qqq") == b.end());
}
TEST(Split, SplitMultiElementString)
{
string a = "qqq www eee";
set<string> b = SplitString(a, ' ');
EXPECT_EQ(3, b.size());
EXPECT_FALSE(b.find("qqq") == b.end());
EXPECT_FALSE(b.find("www") == b.end());
EXPECT_FALSE(b.find("eee") == b.end());
}
TEST(GetCpuInfo, GetCpuInfo)
{
map<string, string> a = GetCpuInfo();
EXPECT_FALSE(a.empty());
EXPECT_TRUE(a.find("") == a.end());
}
TEST(TegraDetector, Detect)
{
EXPECT_TRUE(DetectTegra() != 0);
}
TEST(CpuCount, CheckNonZero)
{
EXPECT_TRUE(GetProcessorCount() != 0);
}
TEST(CpuID, CheckNotEmpy)
{
int cpu_id = GetCpuID();
EXPECT_NE(0, cpu_id);
}
TEST(CpuID, CheckArmV7)
{
int cpu_id = GetCpuID();
EXPECT_TRUE(cpu_id & ARCH_ARMv7);
}
TEST(CpuID, CheckNeon)
{
int cpu_id = GetCpuID();
EXPECT_TRUE(cpu_id & FEATURES_HAS_NEON);
}
TEST(CpuID, CheckVFPv3)
{
int cpu_id = GetCpuID();
EXPECT_TRUE(cpu_id & FEATURES_HAS_VFPv3);
}
TEST(PlatfromDetector, CheckTegra)
{
EXPECT_NE(PLATFORM_UNKNOWN, DetectKnownPlatforms());
}
@@ -0,0 +1,101 @@
#include "IOpenCVEngine.h"
#include "EngineCommon.h"
#include "OpenCVEngine.h"
#include "IPackageManager.h"
#include "PackageManagerStub.h"
#include "PackageInfo.h"
#include "HardwareDetector.h"
#include <gtest/gtest.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>
using namespace android;
class ServiceStarter
{
public:
ServiceStarter()
{
PackageManager = new PackageManagerStub();
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
PackageManager->InstalledPackages.push_back(info);
Engine = new OpenCVEngine(PackageManager);
defaultServiceManager()->addService(IOpenCVEngine::descriptor, Engine);
LOGI("OpenCVEngine native service started successfully");
ProcessState::self()->startThreadPool();
}
~ServiceStarter()
{
delete PackageManager;
}
private:
PackageManagerStub* PackageManager;
sp<IBinder> Engine;
};
static ServiceStarter Starter;
sp<IOpenCVEngine> InitConnect()
{
sp<IServiceManager> ServiceManager = defaultServiceManager();
sp<IBinder> EngineService;
sp<IOpenCVEngine> Engine;
do
{
EngineService = ServiceManager->getService(IOpenCVEngine::descriptor);
if (EngineService != 0) break;
usleep(500000); // 0.5 s
} while(true);
Engine = interface_cast<IOpenCVEngine>(EngineService);
return Engine;
}
TEST(OpenCVEngineTest, GetVersion)
{
sp<IOpenCVEngine> Engine = InitConnect();
EXPECT_FALSE(NULL == Engine.get());
int32_t Version = Engine->GetVersion();
EXPECT_EQ(OPEN_CV_ENGINE_VERSION, Version);
}
TEST(OpenCVEngineTest, InstallVersion)
{
sp<IOpenCVEngine> Engine = InitConnect();
EXPECT_FALSE(NULL == Engine.get());
bool result = Engine->InstallVersion(String16("2.4"));
EXPECT_EQ(true, result);
}
TEST(OpenCVEngineTest, GetPathForExistVersion)
{
sp<IOpenCVEngine> Engine = InitConnect();
EXPECT_FALSE(NULL == Engine.get());
String16 result = Engine->GetLibPathByVersion(String16("2.3"));
EXPECT_STREQ("/data/data/org.opencv.lib_v23_armv7/lib",String8(result).string());
}
TEST(OpenCVEngineTest, GetPathForUnExistVersion)
{
sp<IOpenCVEngine> Engine = InitConnect();
EXPECT_FALSE(NULL == Engine.get());
String16 result = Engine->GetLibPathByVersion(String16("2.5"));
EXPECT_EQ(0, result.size());
}
TEST(OpenCVEngineTest, InstallAndGetVersion)
{
sp<IOpenCVEngine> Engine = InitConnect();
EXPECT_FALSE(NULL == Engine.get());
EXPECT_TRUE(Engine->InstallVersion(String16("2.5")));
String16 result = Engine->GetLibPathByVersion(String16("2.5"));
EXPECT_STREQ("/data/data/org.opencv.lib_v25_tegra3/lib", String8(result).string());
}
@@ -0,0 +1,127 @@
#include "HardwareDetector.h"
#include "IPackageManager.h"
#include "IOpenCVEngine.h"
#include "PackageInfo.h"
#include <gtest/gtest.h>
#include <set>
#include <string>
#include <vector>
using namespace std;
TEST(PackageInfo, FullNameArmv7)
{
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
string name = info.GetFullName();
EXPECT_STREQ("org.opencv.lib_v23_armv7", name.c_str());
}
TEST(PackageInfo, FullNameArmv7Neon)
{
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
string name = info.GetFullName();
EXPECT_STREQ("org.opencv.lib_v23_armv7", name.c_str());
// TODO: Replace if seporate package will be exists
//EXPECT_STREQ("org.opencv.lib_v23_armv7_neon", name.c_str());
}
TEST(PackageInfo, FullNameArmv7VFPv3)
{
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3);
string name = info.GetFullName();
EXPECT_STREQ("org.opencv.lib_v23_armv7", name.c_str());
// TODO: Replace if seporate package will be exists
//EXPECT_STREQ("org.opencv.lib_v23_armv7_vfpv3", name.c_str());
}
TEST(PackageInfo, FullNameArmv7VFPv3Neon)
{
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON);
string name = info.GetFullName();
EXPECT_STREQ("org.opencv.lib_v23_armv7", name.c_str());
// TODO: Replace if seporate package will be exists
//EXPECT_STREQ("org.opencv.lib_v23_armv7_neon", name.c_str());
}
TEST(PackageInfo, FullNameX86SSE2)
{
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
string name = info.GetFullName();
EXPECT_STREQ("org.opencv.lib_v23_x86", name.c_str());
// TODO: Replace if seporate package will be exists
//EXPECT_STREQ("org.opencv.lib_v23_x86_sse2", name.c_str());
}
TEST(PackageInfo, Armv7VFPv3NeonFromFullName)
{
PackageInfo info("org.opencv.lib_v23_armv7_vfpv3_neon", "/data/data/org.opencv.lib_v23_armv7_vfpv3_neon");
EXPECT_EQ("230", info.GetVersion());
EXPECT_EQ(ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON, info.GetCpuID());
}
TEST(PackageInfo, X86SSE2FromFullName)
{
PackageInfo info("org.opencv.lib_v24_x86_sse2", "/data/data/org.opencv.lib_v24_x86_sse2");
EXPECT_EQ(PLATFORM_UNKNOWN, info.GetPlatform());
EXPECT_EQ(ARCH_X86 | FEATURES_HAS_SSE2, info.GetCpuID());
EXPECT_EQ("240", info.GetVersion());
}
TEST(PackageInfo, Tegra2FromFullName)
{
PackageInfo info("org.opencv.lib_v23_tegra2", "/data/data/org.opencv.lib_v23_tegra2");
EXPECT_EQ("230", info.GetVersion());
EXPECT_EQ(PLATFORM_TEGRA2, info.GetPlatform());
}
TEST(PackageInfo, Tegra3FromFullName)
{
PackageInfo info("org.opencv.lib_v24_tegra3", "/data/data/org.opencv.lib_v24_tegra3");
EXPECT_EQ("240", info.GetVersion());
EXPECT_EQ(PLATFORM_TEGRA3, info.GetPlatform());
}
TEST(PackageInfo, FullNameTegra3)
{
PackageInfo info("230", PLATFORM_TEGRA3, 0);
EXPECT_TRUE(!info.IsValid());
// TODO: Replace if seporate package will be exists
//string name = info.GetFullName();
//EXPECT_STREQ("org.opencv.lib_v23_tegra3", name.c_str());
}
TEST(PackageInfo, FullNameTegra2)
{
PackageInfo info("230", PLATFORM_TEGRA2, 0);
EXPECT_TRUE(!info.IsValid());
// TODO: Replace if seporate package will be exists
//string name = info.GetFullName();
//EXPECT_STREQ("org.opencv.lib_v23_tegra2", name.c_str());
}
TEST(PackageInfo, Comparator1)
{
PackageInfo info1("240", PLATFORM_UNKNOWN, ARCH_X86);
PackageInfo info2("org.opencv.lib_v24_x86", "/data/data/org.opencv.lib_v24_x86");
EXPECT_STREQ(info1.GetFullName().c_str(), info2.GetFullName().c_str());
EXPECT_EQ(info1, info2);
}
TEST(PackageInfo, Comparator2)
{
PackageInfo info1("240", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON | FEATURES_HAS_VFPv3);
PackageInfo info2("org.opencv.lib_v24_armv7", "/data/data/org.opencv.lib_v24_armv7");
// TODO: Replace if seporate package will be exists
//PackageInfo info2("org.opencv.lib_v24_armv7_vfpv3_neon", "/data/data/org.opencv.lib_v24_armv7_vfpv3_neon");
EXPECT_STREQ(info1.GetFullName().c_str(), info2.GetFullName().c_str());
EXPECT_EQ(info1, info2);
}
// TODO: Enable test if seporate package will be exists
// TEST(PackageInfo, Comparator3)
// {
// PackageInfo info1("230", PLATFORM_TEGRA2, 0);
// PackageInfo info2("org.opencv.lib_v23_tegra2", "/data/data/org.opencv.lib_v23_tegra2");
// EXPECT_STREQ(info1.GetFullName().c_str(), info2.GetFullName().c_str());
// EXPECT_EQ(info1, info2);
// }
@@ -0,0 +1,18 @@
#include "PackageManagerStub.h"
using namespace std;
bool PackageManagerStub::InstallPackage(const PackageInfo& package)
{
InstalledPackages.push_back(PackageInfo(package.GetFullName(), "/data/data/" + package.GetFullName()));
return true;
}
vector<PackageInfo> PackageManagerStub::GetInstalledPackages()
{
return InstalledPackages;
}
PackageManagerStub::~PackageManagerStub()
{
}
@@ -0,0 +1,17 @@
#ifndef __PACKAGE_MANAGER_STUB_H__
#define __PACKAGE_MANAGER_STUB_H__
#include "IPackageManager.h"
#include "CommonPackageManager.h"
class PackageManagerStub: public CommonPackageManager
{
public:
std::vector<PackageInfo> InstalledPackages;
virtual ~PackageManagerStub();
protected:
virtual bool InstallPackage(const PackageInfo& package);
virtual std::vector<PackageInfo> GetInstalledPackages();
};
#endif
@@ -0,0 +1,100 @@
#include "HardwareDetector.h"
#include "IPackageManager.h"
#include "CommonPackageManager.h"
#include "PackageManagerStub.h"
#include "IOpenCVEngine.h"
#include <utils/String16.h>
#include <gtest/gtest.h>
#include <set>
#include <string>
#include <vector>
using namespace std;
TEST(PackageManager, InstalledVersions)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
pm.InstalledPackages.push_back(info);
std::set<string> versions = pm.GetInstalledVersions();
EXPECT_EQ(1, versions.size());
EXPECT_EQ("230", *versions.begin());
}
TEST(PackageManager, CheckVersionInstalled)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_TEGRA3, 0);
pm.InstalledPackages.push_back(info);
EXPECT_TRUE(pm.CheckVersionInstalled("230", PLATFORM_TEGRA3, 0));
}
TEST(PackageManager, InstallVersion)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_TEGRA3, 0);
pm.InstalledPackages.push_back(info);
EXPECT_TRUE(pm.InstallVersion("240", PLATFORM_TEGRA3, 0));
EXPECT_EQ(2, pm.InstalledPackages.size());
EXPECT_TRUE(pm.CheckVersionInstalled("240", PLATFORM_TEGRA3, 0));
}
TEST(PackageManager, GetPackagePathForArmv7)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
pm.InstalledPackages.push_back(info);
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_ARMv7);
EXPECT_STREQ("/data/data/org.opencv.lib_v23_armv7/lib", path.c_str());
}
TEST(PackageManager, GetPackagePathForArmv7Neon)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
pm.InstalledPackages.push_back(info);
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON);
EXPECT_STREQ("/data/data/org.opencv.lib_v23_armv7/lib", path.c_str());
// TODO: Replace if seporate package will be exists
//EXPECT_STREQ("/data/data/org.opencv.lib_v23_armv7_neon/lib", path.c_str());
}
TEST(PackageManager, GetPackagePathForX86)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_X86);
pm.InstalledPackages.push_back(info);
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_X86);
EXPECT_STREQ("/data/data/org.opencv.lib_v23_x86/lib", path.c_str());
}
TEST(PackageManager, GetPackagePathForX86SSE2)
{
PackageManagerStub pm;
PackageInfo info("230", PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
pm.InstalledPackages.push_back(info);
string path = pm.GetPackagePathByVersion("230", PLATFORM_UNKNOWN, ARCH_X86 | FEATURES_HAS_SSE2);
EXPECT_STREQ("/data/data/org.opencv.lib_v23_x86/lib", path.c_str());
// TODO: Replace if seporate package will be exists
//EXPECT_STREQ("/data/data/org.opencv.lib_v23_x86_sse2/lib", path.c_str());
}
// TODO: Enable tests if seporate package will be exists
// TEST(PackageManager, GetPackagePathForTegra2)
// {
// PackageManagerStub pm;
// PackageInfo info("240", PLATFORM_TEGRA2, 0);
// pm.InstalledPackages.push_back(info);
// string path = pm.GetPackagePathByVersion("240", PLATFORM_TEGRA2, 0);
// EXPECT_STREQ("/data/data/org.opencv.lib_v24_tegra2/lib", path.c_str());
// }
//
// TEST(PackageManager, GetPackagePathForTegra3)
// {
// PackageManagerStub pm;
// PackageInfo info("230", PLATFORM_TEGRA3, 0);
// pm.InstalledPackages.push_back(info);
// string path = pm.GetPackagePathByVersion("230", PLATFORM_TEGRA3, 0);
// EXPECT_STREQ("/data/data/org.opencv.lib_v23_tegra3/lib", path.c_str());
// }
@@ -0,0 +1,8 @@
#include <gtest/gtest.h>
int main(int argc, char **argv)
{
/* return 0;*/
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+43
View File
@@ -0,0 +1,43 @@
#---------------------------------------------------------------------
# Native test application
#---------------------------------------------------------------------
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
Tests/gtest/gtest-all.cpp \
BinderComponent/ProcReader.cpp \
BinderComponent/TegraDetector.cpp \
BinderComponent/HardwareDetector.cpp \
Tests/PackageManagerStub.cpp \
NativeService/CommonPackageManager.cpp \
NativeService/PackageInfo.cpp \
Tests/PackageManagmentTest.cpp \
Tests/PackageInfoTest.cpp \
Tests/OpenCVEngineTest.cpp \
Tests/TestMain.cpp
# Tests/HardwareDetectionTest.cpp \
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/Tests \
$(LOCAL_PATH)/Tests/gtest \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/BinderComponent \
$(LOCAL_PATH)/NativeService \
$(LOCAL_PATH)/Tests/gtest/include \
$(TOP)/frameworks/base/include \
$(TOP)/system/core/include
LOCAL_CFLAGS += -O0 -DGTEST_HAS_CLONE=0 -DGTEST_OS_LINUX_ANDROID=1 -DGTEST_HAS_TR1_TUPLE=0
LOCAL_LDFLAGS = -Wl,-allow-shlib-undefined
LOCAL_MODULE := OpenCVEngineTestApp
LOCAL_LDLIBS += -lz -lbinder -llog
LOCAL_SHARED_LIBRARIES += libOpenCVEngine
include $(BUILD_EXECUTABLE)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
#ifndef __ENGINE_COMMON_H__
#define __ENGINE_COMMON_H__
// Global tag for Logcat output
#undef LOG_TAG
#define LOG_TAG "OpenCVEngine"
#ifndef OPEN_CV_ENGINE_VERSION
#define OPEN_CV_ENGINE_VERSION 1
#endif
#endif
@@ -0,0 +1,34 @@
#ifndef __IOPENCV_ENGINE_H__
#define __IOPENCV_ENGINE_H__
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String16.h>
// Class name of OpenCV engine binder object. Is needned for connection to service
#define OPECV_ENGINE_CLASSNAME "org.opencv.engine.OpenCVEngineInterface"
enum EngineMethonID
{
OCVE_GET_ENGINE_VERSION = 1,
OCVE_GET_LIB_PATH_BY_VERSION = 2,
OCVE_INSTALL_VERSION = 3,
OCVE_GET_LIB_LIST = 4,
};
using namespace android;
class IOpenCVEngine: public android::IInterface
{
public:
DECLARE_META_INTERFACE(OpenCVEngine)
public:
virtual int GetVersion() = 0;
virtual android::String16 GetLibPathByVersion(android::String16 version) = 0;
virtual android::String16 GetLibraryList(android::String16 version) = 0;
virtual bool InstallVersion(android::String16 version) = 0;
};
#endif
@@ -0,0 +1,17 @@
#ifndef __IPACKAGE_MANAGER__
#define __IPACKAGE_MANAGER__
#include <set>
#include <string>
class IPackageManager
{
public:
virtual std::set<std::string> GetInstalledVersions() = 0;
virtual bool CheckVersionInstalled(const std::string& version, int platform, int cpu_id) = 0;
virtual bool InstallVersion(const std::string&, int platform, int cpu_id) = 0;
virtual std::string GetPackagePathByVersion(const std::string&, int platform, int cpu_id) = 0;
virtual ~IPackageManager(){};
};
#endif
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/InfoName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Version: "
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/InfoVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Target hardware: "
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/InfoHardware"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
+119
View File
@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="About:"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This application allows you to manage OpenCV library on your device."
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/EngineVersionCaption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Version: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/EngineVersionValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="version"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Device information:"
android:textAppearance="?android:attr/textAppearanceLarge" android:layout_marginTop="20dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/HardwareCaption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hardware: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/HardwareValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hardware"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/OsVersionCaption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OS version: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/OsVersionValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Os Specification"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Installed packages:"
android:textAppearance="?android:attr/textAppearanceLarge" android:layout_marginTop="15dp"/>
<ListView
android:id="@+id/InstalledPackageList"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_weight="1">
</ListView>
<Button
android:id="@+id/CheckEngineUpdate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Check Manager update" />
</LinearLayout>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OpenCV Manager</string>
</resources>
@@ -0,0 +1,26 @@
package org.opencv.engine;
import android.os.IBinder;
public class BinderConnector
{
public BinderConnector(MarketConnector Market)
{
Init(Market);
}
public native IBinder Connect();
public boolean Disconnect()
{
Final();
return true;
}
static
{
System.loadLibrary("OpenCVEngine");
System.loadLibrary("OpenCVEngine_jni");
}
private native boolean Init(MarketConnector Market);
public native void Final();
}
@@ -0,0 +1,46 @@
package org.opencv.engine;
public class HardwareDetector
{
public static final int ARCH_UNKNOWN = -1;
public static final int ARCH_X86 = 0x01000000;
public static final int ARCH_X64 = 0x02000000;
public static final int ARCH_ARMv5 = 0x04000000;
public static final int ARCH_ARMv6 = 0x08000000;
public static final int ARCH_ARMv7 = 0x10000000;
public static final int ARCH_ARMv8 = 0x20000000;
// Platform specific features
// ! Check CPU arch before !
// ARM specific features
public static final int FEATURES_HAS_VFPv3d16 = 0x01;
public static final int FEATURES_HAS_VFPv3 = 0x02;
public static final int FEATURES_HAS_NEON = 0x04;
public static final int FEATURES_HAS_NEON2 = 0x08;
// X86 specific features
public static final int FEATURES_HAS_SSE = 0x01;
public static final int FEATURES_HAS_SSE2 = 0x02;
public static final int FEATURES_HAS_SSE3 = 0x04;
// GPU Acceleration options
public static final int FEATURES_HAS_GPU = 0x010000;
public static final int PLATFORM_TEGRA = 1;
public static final int PLATFORM_TEGRA2 = 2;
public static final int PLATFORM_TEGRA3 = 3;
public static final int PLATFORM_UNKNOWN = -1;
// Return CPU arch and list of supported features
public static native int GetCpuID();
// Return hardware platform name
public static native String GetPlatformName();
// Return processor count
public static native int GetProcessorCount();
public static native int DetectKnownPlatforms();
}
@@ -0,0 +1,121 @@
package org.opencv.engine;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
public class MarketConnector
{
protected static final String OpenCVPackageNamePreffix = "org.opencv.lib";
protected Context mContext;
public MarketConnector(Context context)
{
mContext = context;
}
public String GetApplicationName(ApplicationInfo info)
{
return (String) info.loadLabel(mContext.getPackageManager());
}
public boolean InstallAppFromMarket(String AppID)
{
boolean result = true;
try
{
Intent intent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + AppID)
);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
catch(Exception e)
{
result = false;
}
return result;
}
public boolean RemoveAppFromMarket(String AppID, boolean wait)
{
boolean result = true;
try
{
Intent intent = new Intent(
Intent.ACTION_DELETE,
Uri.parse("package:" + AppID)
);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (wait)
{
((Activity)mContext).startActivityForResult(intent, 0);
}
else
{
mContext.startActivity(intent);
}
}
catch(Exception e)
{
e.printStackTrace();
result = false;
}
return result;
}
public boolean CheckPackageInstalled(String AppID)
{
List<PackageInfo> Packages = mContext.getPackageManager().getInstalledPackages(PackageManager.GET_CONFIGURATIONS);
Iterator<PackageInfo> it = Packages.iterator();
while(it.hasNext())
{
PackageInfo CurrentPack = it.next();
if (CurrentPack.packageName == AppID)
{
return true;
}
}
return false;
}
public PackageInfo[] GetInstalledOpenCVPackages()
{
List<PackageInfo> AllPackages = mContext.getPackageManager().getInstalledPackages(PackageManager.GET_CONFIGURATIONS);
List<PackageInfo> OpenCVPackages = new ArrayList<PackageInfo>();
Iterator<PackageInfo> it = AllPackages.iterator();
while(it.hasNext())
{
PackageInfo CurrentPack = it.next();
if (CurrentPack.packageName.contains(OpenCVPackageNamePreffix))
{
OpenCVPackages.add(CurrentPack);
}
}
PackageInfo[] OpenCVPackagesArray = new PackageInfo[OpenCVPackages.size()];
it = OpenCVPackages.iterator();
int idx = 0;
while(it.hasNext())
{
OpenCVPackagesArray[idx] = it.next();
idx++;
}
return OpenCVPackagesArray;
}
}
@@ -0,0 +1,33 @@
package org.opencv.engine;
/**
* Class provides Java interface to OpenCV Engine Service. Is synchronious with native OpenCVEngine class.
*/
interface OpenCVEngineInterface
{
/**
* @return Return service version
*/
int getEngineVersion();
/**
* Find installed OpenCV library
* @param OpenCV version
* @return Returns path to OpenCV native libs or empty string if OpenCV was not found
*/
String getLibPathByVersion(String version);
/**
* Try to install defined version of OpenCV from Google Play (Android Market).
* @param OpenCV version
* @return Returns true if installation was successful or OpenCV package has been already installed
*/
boolean installVersion(String version);
/**
* Return list of libraries in loading order seporated by ";" symbol
* @param OpenCV version
* @return Returns OpenCV libraries names seporated by symbol ";" in loading order
*/
String getLibraryList(String version);
}
@@ -0,0 +1,42 @@
package org.opencv.engine;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class OpenCVEngineService extends Service
{
private static final String TAG = "OpenCVEngine/Service";
private IBinder mEngineInterface;
private MarketConnector mMarket;
private BinderConnector mNativeBinder;
public void onCreate()
{
Log.i(TAG, "Service starting");
super.onCreate();
Log.i(TAG, "Engine binder component creating");
mMarket = new MarketConnector(getBaseContext());
mNativeBinder = new BinderConnector(mMarket);
mEngineInterface = mNativeBinder.Connect();
Log.i(TAG, "Service started successfully");
}
public IBinder onBind(Intent intent)
{
Log.i(TAG, "Service onBind called for intent " + intent.toString());
return mEngineInterface;
}
public boolean onUnbind(Intent intent)
{
Log.i(TAG, "Service onUnbind called for intent " + intent.toString());
return true;
}
public void OnDestroy()
{
Log.i(TAG, "OpenCV Engine service destruction");
mNativeBinder.Disconnect();
}
}
@@ -0,0 +1,52 @@
package org.opencv.engine.manager;
public class HardwareDetector
{
public static final int ARCH_UNKNOWN = -1;
public static final int ARCH_X86 = 0x01000000;
public static final int ARCH_X64 = 0x02000000;
public static final int ARCH_ARMv5 = 0x04000000;
public static final int ARCH_ARMv6 = 0x08000000;
public static final int ARCH_ARMv7 = 0x10000000;
public static final int ARCH_ARMv8 = 0x20000000;
// Platform specific features
// ! Check CPU arch before !
// ARM specific features
public static final int FEATURES_HAS_VFPv3d16 = 0x01;
public static final int FEATURES_HAS_VFPv3 = 0x02;
public static final int FEATURES_HAS_NEON = 0x04;
public static final int FEATURES_HAS_NEON2 = 0x08;
// X86 specific features
public static final int FEATURES_HAS_SSE = 0x01;
public static final int FEATURES_HAS_SSE2 = 0x02;
public static final int FEATURES_HAS_SSE3 = 0x04;
// GPU Acceleration options
public static final int FEATURES_HAS_GPU = 0x010000;
public static final int PLATFORM_TEGRA = 1;
public static final int PLATFORM_TEGRA2 = 2;
public static final int PLATFORM_TEGRA3 = 3;
public static final int PLATFORM_UNKNOWN = 0;
// Return CPU arch and list of supported features
public static native int GetCpuID();
// Return hardware platform name
public static native String GetPlatformName();
// Return processor count
public static native int GetProcessorCount();
public static native int DetectKnownPlatforms();
static
{
System.loadLibrary("OpenCVEngine");
System.loadLibrary("OpenCVEngine_jni");
}
}
@@ -0,0 +1,312 @@
package org.opencv.engine.manager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.opencv.engine.MarketConnector;
import org.opencv.engine.OpenCVEngineInterface;
import org.opencv.engine.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class ManagerActivity extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView OsVersionView = (TextView)findViewById(R.id.OsVersionValue);
OsVersionView.setText(Build.VERSION.CODENAME + " (" + Build.VERSION.RELEASE + "), API " + Build.VERSION.SDK_INT);
mInstalledPackageView = (ListView)findViewById(R.id.InstalledPackageList);
mMarket = new MarketConnector(this);
mInstalledPacksAdapter = new SimpleAdapter(
this,
mListViewItems,
R.layout.info,
new String[] {"Name", "Version", "Hardware"},
new int[] {R.id.InfoName,R.id.InfoVersion, R.id.InfoHardware}
);
mInstalledPackageView.setAdapter(mInstalledPacksAdapter);
TextView HardwarePlatformView = (TextView)findViewById(R.id.HardwareValue);
int Platfrom = HardwareDetector.DetectKnownPlatforms();
int CpuId = HardwareDetector.GetCpuID();
if (HardwareDetector.PLATFORM_UNKNOWN != Platfrom)
{
if (HardwareDetector.PLATFORM_TEGRA == Platfrom)
{
HardwarePlatformView.setText("Tegra");
}
else if (HardwareDetector.PLATFORM_TEGRA == Platfrom)
{
HardwarePlatformView.setText("Tegra 2");
}
else
{
HardwarePlatformView.setText("Tegra 3");
}
}
else
{
if ((CpuId & HardwareDetector.ARCH_X86) == HardwareDetector.ARCH_X86)
{
HardwarePlatformView.setText("x86 " + JoinIntelFeatures(CpuId));
}
else if ((CpuId & HardwareDetector.ARCH_X64) == HardwareDetector.ARCH_X64)
{
HardwarePlatformView.setText("x64 " + JoinIntelFeatures(CpuId));
}
else if ((CpuId & HardwareDetector.ARCH_ARMv5) == HardwareDetector.ARCH_ARMv5)
{
HardwarePlatformView.setText("ARM v5 " + JoinArmFeatures(CpuId));
}
else if ((CpuId & HardwareDetector.ARCH_ARMv6) == HardwareDetector.ARCH_ARMv6)
{
HardwarePlatformView.setText("ARM v6 " + JoinArmFeatures(CpuId));
}
else if ((CpuId & HardwareDetector.ARCH_ARMv7) == HardwareDetector.ARCH_ARMv7)
{
HardwarePlatformView.setText("ARM v7 " + JoinArmFeatures(CpuId));
}
else if ((CpuId & HardwareDetector.ARCH_ARMv8) == HardwareDetector.ARCH_ARMv8)
{
HardwarePlatformView.setText("ARM v8 " + JoinArmFeatures(CpuId));
}
else
{
HardwarePlatformView.setText("not detected");
}
}
mUpdateEngineButton = (Button)findViewById(R.id.CheckEngineUpdate);
mUpdateEngineButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (!mMarket.InstallAppFromMarket("org.opencv.engine"))
{
Toast toast = Toast.makeText(getApplicationContext(), "Google Play is not avaliable", Toast.LENGTH_SHORT);
toast.show();
}
}
});
mActionDialog = new AlertDialog.Builder(this).create();
mActionDialog.setTitle("Choose action");
mActionDialog.setButton("Update", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
int index = (Integer)mInstalledPackageView.getTag();
if (!mMarket.InstallAppFromMarket(mInstalledPackageInfo[index].packageName))
{
Toast toast = Toast.makeText(getApplicationContext(), "Google Play is not avaliable", Toast.LENGTH_SHORT);
toast.show();
}
}
});
mActionDialog.setButton3("Remove", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
int index = (Integer)mInstalledPackageView.getTag();
if (!mMarket.RemoveAppFromMarket(mInstalledPackageInfo[index].packageName, true))
{
Toast toast = Toast.makeText(getApplicationContext(), "Google Play is not avaliable", Toast.LENGTH_SHORT);
toast.show();
}
}
});
mActionDialog.setButton2("Return", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// nothing
}
});
mInstalledPackageView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) {
mInstalledPackageView.setTag(new Integer((int)id));
mActionDialog.show();
}
});
if (!bindService(new Intent("org.opencv.engine.BIND"), mServiceConnection, Context.BIND_AUTO_CREATE))
{
TextView EngineVersionView = (TextView)findViewById(R.id.EngineVersionValue);
EngineVersionView.setText("not avaliable");
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addAction(Intent.ACTION_PACKAGE_INSTALL);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
registerReceiver(mPackageChangeReciever, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mPackageChangeReciever);
}
@Override
protected void onResume() {
super.onResume();
FillPackageList();
}
protected SimpleAdapter mInstalledPacksAdapter;
protected ListView mInstalledPackageView;
protected Button mUpdateEngineButton;
protected PackageInfo[] mInstalledPackageInfo;
protected static final ArrayList<HashMap<String,String>> mListViewItems = new ArrayList<HashMap<String,String>>();
protected MarketConnector mMarket;
AlertDialog mActionDialog;
protected BroadcastReceiver mPackageChangeReciever = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("OpenCV Manager/Reciever", "Bradcast message " + intent.getAction() + " reciever");
FillPackageList();
}
};
protected ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
public void onServiceConnected(ComponentName name, IBinder service) {
TextView EngineVersionView = (TextView)findViewById(R.id.EngineVersionValue);
OpenCVEngineInterface EngineService = OpenCVEngineInterface.Stub.asInterface(service);
try {
EngineVersionView.setText("" + EngineService.getEngineVersion());
} catch (RemoteException e) {
EngineVersionView.setText("not avaliable");
e.printStackTrace();
}
unbindService(mServiceConnection);
}
};
protected void FillPackageList()
{
mInstalledPackageInfo = mMarket.GetInstalledOpenCVPackages();
mListViewItems.clear();
for (int i = 0; i < mInstalledPackageInfo.length; i++)
{
// Convert to Items for package list view
HashMap<String,String> temp = new HashMap<String,String>();
temp.put("Name", mMarket.GetApplicationName(mInstalledPackageInfo[i].applicationInfo));
int idx = 0;
String OpenCVersion = "unknown";
String HardwareName = "";
StringTokenizer tokenizer = new StringTokenizer(mInstalledPackageInfo[i].packageName, "_");
while (tokenizer.hasMoreTokens())
{
if (idx == 1)
{
// version of OpenCV
OpenCVersion = tokenizer.nextToken().substring(1);
}
else if (idx >= 2)
{
// hardware options
HardwareName += tokenizer.nextToken() + " ";
}
else
{
tokenizer.nextToken();
}
idx++;
}
temp.put("Version", NormalizeVersion(OpenCVersion, mInstalledPackageInfo[i].versionName));
temp.put("Hardware", HardwareName);
mListViewItems.add(temp);
}
mInstalledPacksAdapter.notifyDataSetChanged();
}
protected String NormalizeVersion(String OpenCVersion, String PackageVersion)
{
int dot = PackageVersion.indexOf(".");
return OpenCVersion.substring(0, OpenCVersion.length()-1) + "." +
OpenCVersion.toCharArray()[OpenCVersion.length()-1] + "." +
PackageVersion.substring(0, dot) + " rev " + PackageVersion.substring(dot+1);
}
protected String ConvertPackageName(String Name, String Version)
{
return Name + " rev " + Version;
}
protected String JoinIntelFeatures(int features)
{
// TODO: update if package will be published
return "";
}
protected String JoinArmFeatures(int features)
{
// TODO: update if package will be published
if ((features & HardwareDetector.FEATURES_HAS_NEON) == HardwareDetector.FEATURES_HAS_NEON)
{
return "with Neon";
}
else if ((features & HardwareDetector.FEATURES_HAS_VFPv3) == HardwareDetector.FEATURES_HAS_VFPv3)
{
return "with VFP v3";
}
else if ((features & HardwareDetector.FEATURES_HAS_VFPv3d16) == HardwareDetector.FEATURES_HAS_VFPv3d16)
{
return "with VFP v3d16";
}
else
{
return "";
}
}
}
@@ -0,0 +1,16 @@
package org.opencv.engine.manager;
public class OpenCVPackageInfo
{
public OpenCVPackageInfo(String PackageName, String PackageInstallPath, String RevName)
{
}
protected long mNativeObject = 0;
protected static native long nativeConstructor(String PackageName, String PackageInstallPath, String RevName);
protected static native void nativeDestructor(long nativeAddress);
protected static native String nativeGetVersion(long thiz);
protected static native String nativeGetPlatfrom(long thiz);
}