diff --git a/android/service/engine/CMakeLists.txt b/android/service/engine/CMakeLists.txt index 5b723867cad9f34239a939a87fb3e9520f96439e..14066831a614bde453628ad964ec9dbf6c071c2c 100644 --- a/android/service/engine/CMakeLists.txt +++ b/android/service/engine/CMakeLists.txt @@ -2,7 +2,7 @@ set(engine OpenCVEngine) set(JNI_LIB_NAME ${engine} ${engine}_jni) unset(__android_project_chain CACHE) -add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 8 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON IGNORE_MANIFEST ON ) +add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 9 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON IGNORE_MANIFEST ON ) set(ANDROID_PLATFORM_VERSION_CODE "0") diff --git a/android/service/engine/build.xml b/android/service/engine/build.xml index a16a4fefbaf1c52249ca136e4859861fc4afdb9d..98ddc3eac178619430fc6e4134c1c1fd1a716d5c 100644 --- a/android/service/engine/build.xml +++ b/android/service/engine/build.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<project name="ManagerActivity" default="help"> +<project name="OpenCV Manager" default="help"> <!-- The local.properties file is created and updated by the 'android' tool. It contains the path to the SDK. It should *NOT* be checked into diff --git a/android/service/engine/jni/Android.mk b/android/service/engine/jni/Android.mk index 9ab92a2089b801f7f38776c2afa4562c086f1f66..71d2c464c99d19c8e801827458d9f38c60edb7e1 100644 --- a/android/service/engine/jni/Android.mk +++ b/android/service/engine/jni/Android.mk @@ -52,7 +52,8 @@ LOCAL_SRC_FILES := \ NativeService/CommonPackageManager.cpp \ JNIWrapper/JavaBasedPackageManager.cpp \ NativeService/PackageInfo.cpp \ - JNIWrapper/HardwareDetector_jni.cpp + JNIWrapper/HardwareDetector_jni.cpp \ + JNIWrapper/OpenCVLibraryInfo.cpp LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ diff --git a/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp b/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1cbccfe83da18c3784a8f18fc56fa18cfeff122 --- /dev/null +++ b/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.cpp @@ -0,0 +1,88 @@ +#include "OpenCVLibraryInfo.h" +#include "EngineCommon.h" +#include <utils/Log.h> +#include <dlfcn.h> + +JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open + (JNIEnv * env, jobject, jstring str) +{ + const char* infoLibPath = env->GetStringUTFChars(str, NULL); + if (infoLibPath == NULL) + return 0; + + LOGD("Trying to load info library \"%s\"", infoLibPath); + + void* handle; + + handle = dlopen(infoLibPath, RTLD_LAZY); + if (handle == NULL) + LOGI("Info library not found by path \"%s\"", infoLibPath); + + return (jlong)handle; +} + +JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageName + (JNIEnv* env, jobject, jlong handle) +{ + const char* (*info_func)(); + const char* result; + const char* error; + + dlerror(); + *(void **) (&info_func) = dlsym((void*)handle, "GetPackageName"); + if ((error = dlerror()) == NULL) + result = (*info_func)(); + else + { + LOGE("dlsym error: \"%s\"", error); + result = "unknown"; + } + + return env->NewStringUTF(result); +} + +JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryList + (JNIEnv* env, jobject, jlong handle) +{ + const char* (*info_func)(); + const char* result; + const char* error; + + dlerror(); + *(void **) (&info_func) = dlsym((void*)handle, "GetLibraryList"); + if ((error = dlerror()) == NULL) + result = (*info_func)(); + else + { + LOGE("dlsym error: \"%s\"", error); + result = "unknown"; + } + + return env->NewStringUTF(result); +} + +JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionName + (JNIEnv* env, jobject, jlong handle) +{ + const char* (*info_func)(); + const char* result; + const char* error; + + dlerror(); + *(void **) (&info_func) = dlsym((void*)handle, "GetRevision"); + if ((error = dlerror()) == NULL) + result = (*info_func)(); + else + { + LOGE("dlsym error: \"%s\"", error); + result = "unknown"; + } + + return env->NewStringUTF(result); +} + +JNIEXPORT void JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_close + (JNIEnv*, jobject, jlong handle) +{ + dlclose((void*)handle); +} diff --git a/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h b/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..b02050ffde839268f4568d74a8639666d8b92bfc --- /dev/null +++ b/android/service/engine/jni/JNIWrapper/OpenCVLibraryInfo.h @@ -0,0 +1,27 @@ +#include <jni.h> + +#ifndef _Included_org_opencv_engine_OpenCVLibraryInfo +#define _Included_org_opencv_engine_OpenCVLibraryInfo +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT jlong JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_open + (JNIEnv *, jobject, jstring); + +JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getPackageName + (JNIEnv *, jobject, jlong); + +JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getLibraryList + (JNIEnv *, jobject, jlong); + +JNIEXPORT jstring JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_getVersionName + (JNIEnv *, jobject, jlong); + +JNIEXPORT void JNICALL Java_org_opencv_engine_OpenCVLibraryInfo_close + (JNIEnv *, jobject, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/android/service/engine/project.properties b/android/service/engine/project.properties index 85aac54016de57ee00f09a8d81bf3ff6a7373e82..c6998b3d1014ea7f9d4d6d09805f83a7f4681cbd 100644 --- a/android/service/engine/project.properties +++ b/android/service/engine/project.properties @@ -11,4 +11,4 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-8 +target=android-9 diff --git a/android/service/engine/src/org/opencv/engine/MarketConnector.java b/android/service/engine/src/org/opencv/engine/MarketConnector.java index 5a5c098686f6e1369f2378618c6e36f38ce9c8a9..da595915f2ba08f91cbde5150f5a61753064a39d 100644 --- a/android/service/engine/src/org/opencv/engine/MarketConnector.java +++ b/android/service/engine/src/org/opencv/engine/MarketConnector.java @@ -20,8 +20,6 @@ public class MarketConnector private static final String TAG = "OpenCVEngine/MarketConnector"; protected Context mContext; - public boolean mIncludeManager = true; - public MarketConnector(Context context) { mContext = context; @@ -100,15 +98,13 @@ public class MarketConnector { List<PackageInfo> AllPackages = mContext.getPackageManager().getInstalledPackages(PackageManager.GET_CONFIGURATIONS); List<PackageInfo> OpenCVPackages = new ArrayList<PackageInfo>(); - if (mIncludeManager) - { - try { - OpenCVPackages.add(mContext.getPackageManager().getPackageInfo("org.opencv.engine", PackageManager.GET_CONFIGURATIONS)); - } catch (NameNotFoundException e) { - Log.e(TAG, "OpenCV Manager package info was not found!"); - e.printStackTrace(); - } + try { + OpenCVPackages.add(mContext.getPackageManager().getPackageInfo("org.opencv.engine", PackageManager.GET_CONFIGURATIONS)); + } catch (NameNotFoundException e) { + Log.e(TAG, "OpenCV Manager package info was not found!"); + e.printStackTrace(); } + Iterator<PackageInfo> it = AllPackages.iterator(); while(it.hasNext()) { diff --git a/android/service/engine/src/org/opencv/engine/OpenCVLibraryInfo.java b/android/service/engine/src/org/opencv/engine/OpenCVLibraryInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..d0f67bfde0fd57aa22007e25ca26fa7acac7d500 --- /dev/null +++ b/android/service/engine/src/org/opencv/engine/OpenCVLibraryInfo.java @@ -0,0 +1,40 @@ +package org.opencv.engine; + +public class OpenCVLibraryInfo { + public OpenCVLibraryInfo(String packagePath) { + mNativeObj = open(packagePath + "/libopencv_info.so"); + if (mNativeObj != 0) { + mPackageName = getPackageName(mNativeObj); + mLibraryList = getLibraryList(mNativeObj); + mVersionName = getVersionName(mNativeObj); + close(mNativeObj); + } + } + + public boolean status() { + return (mNativeObj != 0); + } + + public String packageName() { + return mPackageName; + } + + public String libraryList() { + return mLibraryList; + } + + public String versionName() { + return mVersionName; + } + + private long mNativeObj; + private String mPackageName; + private String mLibraryList; + private String mVersionName; + + private native long open(String packagePath); + private native String getPackageName(long obj); + private native String getLibraryList(long obj); + private native String getVersionName(long obj); + private native void close(long obj); +} diff --git a/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java b/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java index 8bb2cd76ed6a267a0ec7c5d2d6ab9a9568b8fde7..13f6c8f50ff86eae652d01b3531f6a382b95c694 100644 --- a/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java +++ b/android/service/engine/src/org/opencv/engine/manager/ManagerActivity.java @@ -7,7 +7,9 @@ import java.util.StringTokenizer; import org.opencv.engine.HardwareDetector; import org.opencv.engine.MarketConnector; import org.opencv.engine.OpenCVEngineInterface; +import org.opencv.engine.OpenCVLibraryInfo; import org.opencv.engine.R; +import android.annotation.TargetApi; import android.app.Activity; import android.app.AlertDialog; import android.content.BroadcastReceiver; @@ -77,7 +79,7 @@ public class ManagerActivity extends Activity { HardwarePlatformView.setText("Tegra"); } - else if (HardwareDetector.PLATFORM_TEGRA == Platfrom) + else if (HardwareDetector.PLATFORM_TEGRA2 == Platfrom) { HardwarePlatformView.setText("Tegra 2"); } @@ -170,9 +172,13 @@ public class ManagerActivity extends Activity mInstalledPackageView.setOnItemClickListener(new OnItemClickListener() { - public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) { - mInstalledPackageView.setTag(Integer.valueOf((int)id)); - mActionDialog.show(); + public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { + //if (!mListViewItems.get((int) id).get("Name").equals("Built-in OpenCV library")); + if (!mInstalledPackageInfo[(int) id].packageName.equals("org.opencv.engine")) + { + mInstalledPackageView.setTag(Integer.valueOf((int)id)); + mActionDialog.show(); + } } }); @@ -232,8 +238,6 @@ public class ManagerActivity extends Activity protected class OpenCVEngineServiceConnection implements ServiceConnection { public void onServiceDisconnected(ComponentName name) { - // TODO Auto-generated method stub - } public void onServiceConnected(ComponentName name, IBinder service) { @@ -266,23 +270,58 @@ public class ManagerActivity extends Activity } }; + @TargetApi(Build.VERSION_CODES.GINGERBREAD) synchronized protected void FillPackageList() { synchronized (mListViewItems) { - mMarket.mIncludeManager = false; mInstalledPackageInfo = mMarket.GetInstalledOpenCVPackages(); mListViewItems.clear(); - for (int i = 0; i < mInstalledPackageInfo.length; i++) + int RealPackageCount = mInstalledPackageInfo.length; + for (int i = 0; i < RealPackageCount; i++) { + if (mInstalledPackageInfo[i] == null) + break; + // Convert to Items for package list view HashMap<String,String> temp = new HashMap<String,String>(); + + String HardwareName = ""; + String NativeLibDir = ""; + String OpenCVersion = ""; + String PublicName = mMarket.GetApplicationName(mInstalledPackageInfo[i].applicationInfo); + String PackageName = mInstalledPackageInfo[i].packageName; + String VersionName = mInstalledPackageInfo[i].versionName; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) + NativeLibDir = mInstalledPackageInfo[i].applicationInfo.nativeLibraryDir; + else + NativeLibDir = "/data/data/" + mInstalledPackageInfo[i].packageName + "/lib"; + + OpenCVLibraryInfo NativeInfo = new OpenCVLibraryInfo(NativeLibDir); + + if (PackageName.equals("org.opencv.engine")) + { + if (NativeInfo.status()) + { + PublicName = "Built-in OpenCV library"; + PackageName = NativeInfo.packageName(); + VersionName = NativeInfo.versionName(); + } + else + { + mInstalledPackageInfo[i] = mInstalledPackageInfo[RealPackageCount-1]; + mInstalledPackageInfo[RealPackageCount-1] = null; + RealPackageCount--; + i--; + continue; + } + } int idx = 0; - String OpenCVersion = "unknown"; - String HardwareName = ""; - StringTokenizer tokenizer = new StringTokenizer(mInstalledPackageInfo[i].packageName, "_"); + Log.d(TAG, PackageName); + StringTokenizer tokenizer = new StringTokenizer(PackageName, "_"); while (tokenizer.hasMoreTokens()) { if (idx == 1) @@ -303,6 +342,7 @@ public class ManagerActivity extends Activity } String ActivePackagePath; + String Tags = null; ActivePackagePath = mActivePackageMap.get(OpenCVersion); Log.d(TAG, OpenCVersion + " -> " + ActivePackagePath); @@ -313,7 +353,7 @@ public class ManagerActivity extends Activity if (start >= 0 && ActivePackagePath.charAt(stop) == '/') { temp.put("Activity", "y"); - PublicName += " (in use)"; + Tags = "active"; } else { @@ -325,9 +365,32 @@ public class ManagerActivity extends Activity temp.put("Activity", "n"); } + temp.put("Version", NormalizeVersion(OpenCVersion, VersionName)); + // HACK: OpenCV Manager for Armv7-a Neon already has Tegra3 optimizations + // that is enabled on proper hardware + if (HardwareDetector.DetectKnownPlatforms() == HardwareDetector.PLATFORM_TEGRA3 && + HardwareName.equals("armv7a neon ") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) + { + temp.put("Hardware", "Tegra 3"); + if (Tags == null) + { + Tags = "optimized"; + } + else + { + Tags = Tags + ", optimized"; + } + } + else + { + temp.put("Hardware", HardwareName); + } + + if (Tags != null) + PublicName = PublicName + " (" + Tags + ")"; + temp.put("Name", PublicName); - temp.put("Version", NormalizeVersion(OpenCVersion, mInstalledPackageInfo[i].versionName)); - temp.put("Hardware", HardwareName); + mListViewItems.add(temp); }