package org.opencv.android;
import java.io.File;
import java.util.StringTokenizer;
import org.opencv.core.Core;
import org.opencv.engine.OpenCVEngineInterface;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
class AsyncServiceHelper
{
public static boolean initOpenCV(String Version, final Context AppContext,
final LoaderCallbackInterface Callback)
{
AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback);
if (AppContext.bindService(new Intent("org.opencv.engine.BIND"),
helper.mServiceConnection, Context.BIND_AUTO_CREATE))
{
return true;
}
else
{
AppContext.unbindService(helper.mServiceConnection);
InstallService(AppContext, Callback);
return false;
}
}
protected AsyncServiceHelper(String Version, Context AppContext, LoaderCallbackInterface Callback)
{
mOpenCVersion = Version;
mUserAppCallback = Callback;
mAppContext = AppContext;
}
protected static final String TAG = "OpenCVManager/Helper";
protected static final int MINIMUM_ENGINE_VERSION = 2;
protected OpenCVEngineInterface mEngineService;
protected LoaderCallbackInterface mUserAppCallback;
protected String mOpenCVersion;
protected Context mAppContext;
protected static boolean mServiceInstallationProgress = false;
protected static boolean mLibraryInstallationProgress = false;
protected static boolean InstallServiceQuiet(Context context)
{
boolean result = true;
try
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(OPEN_CV_SERVICE_URL));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
catch(Exception e)
{
result = false;
}
return result;
}
protected static void InstallService(final Context AppContext, final LoaderCallbackInterface Callback)
{
if (!mServiceInstallationProgress)
{
Log.d(TAG, "Request new service installation");
InstallCallbackInterface InstallQuery = new InstallCallbackInterface() {
private LoaderCallbackInterface mUserAppCallback = Callback;
public String getPackageName()
{
return "OpenCV Manager";
}
public void install() {
Log.d(TAG, "Trying to install OpenCV Manager via Google Play");
boolean result = InstallServiceQuiet(AppContext);
if (result)
{
mServiceInstallationProgress = true;
Log.d(TAG, "Package installation started");
}
else
{
Log.d(TAG, "OpenCV package was not installed!");
int Status = LoaderCallbackInterface.MARKET_ERROR;
Log.d(TAG, "Init finished with status " + Status);
Log.d(TAG, "Unbind from service");
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(Status);
}
}
public void cancel()
{
Log.d(TAG, "OpenCV library installation was canceled");
int Status = LoaderCallbackInterface.INSTALL_CANCELED;
Log.d(TAG, "Init finished with status " + Status);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(Status);
}
public void wait_install()
{
Log.e(TAG, "Instalation was not started! Nothing to wait!");
}
};
Callback.onPackageInstall(InstallCallbackInterface.NEW_INSTALLATION, InstallQuery);
}
else
{
Log.d(TAG, "Waiting current installation process");
InstallCallbackInterface WaitQuery = new InstallCallbackInterface() {
private LoaderCallbackInterface mUserAppCallback = Callback;
public String getPackageName()
{
return "OpenCV Manager";
}
public void install()
{
Log.e(TAG, "Nothing to install we just wait current installation");
}
public void cancel()
{
Log.d(TAG, "Wating for OpenCV canceled by user");
mServiceInstallationProgress = false;
int Status = LoaderCallbackInterface.INSTALL_CANCELED;
Log.d(TAG, "Init finished with status " + Status);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(Status);
}
public void wait_install()
{
InstallServiceQuiet(AppContext);
}
};
Callback.onPackageInstall(InstallCallbackInterface.INSTALLATION_PROGRESS, WaitQuery);
}
}
/**
* URL of OpenCV Manager page on Google Play Market.
*/
protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine";
protected ServiceConnection mServiceConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder service)
{
Log.d(TAG, "Service connection created");
mEngineService = OpenCVEngineInterface.Stub.asInterface(service);
if (null == mEngineService)
{
Log.d(TAG, "OpenCV Manager Service connection fails. May be service was not installed?");
InstallService(mAppContext, mUserAppCallback);
}
else
{
mServiceInstallationProgress = false;
try
{
if (mEngineService.getEngineVersion() < MINIMUM_ENGINE_VERSION)
{
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INCOMPATIBLE_MANAGER_VERSION);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INCOMPATIBLE_MANAGER_VERSION);
return;
}
Log.d(TAG, "Trying to get library path");
String path = mEngineService.getLibPathByVersion(mOpenCVersion);
if ((null == path) || (path.length() == 0))
{
if (!mLibraryInstallationProgress)
{
InstallCallbackInterface InstallQuery = new InstallCallbackInterface() {
public String getPackageName()
{
return "OpenCV library";
}
public void install() {
Log.d(TAG, "Trying to install OpenCV lib via Google Play");
try
{
if (mEngineService.installVersion(mOpenCVersion))
{
mLibraryInstallationProgress = true;
Log.d(TAG, "Package installation statred");
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
}
else
{
Log.d(TAG, "OpenCV package was not installed!");
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.MARKET_ERROR);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.MARKET_ERROR);
}
} catch (RemoteException e) {
e.printStackTrace();;
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INIT_FAILED);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INIT_FAILED);
}
}
public void cancel() {
Log.d(TAG, "OpenCV library installation was canceled");
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INSTALL_CANCELED);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INSTALL_CANCELED);
}
public void wait_install() {
Log.e(TAG, "Instalation was not started! Nothing to wait!");
}
};
mUserAppCallback.onPackageInstall(InstallCallbackInterface.NEW_INSTALLATION, InstallQuery);
}
else
{
InstallCallbackInterface WaitQuery = new InstallCallbackInterface() {
public String getPackageName()
{
return "OpenCV library";
}
public void install() {
Log.e(TAG, "Nothing to install we just wait current installation");
}
public void cancel()
{
Log.d(TAG, "OpenCV library installation was canceled");
mLibraryInstallationProgress = false;
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INSTALL_CANCELED);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INSTALL_CANCELED);
}
public void wait_install() {
Log.d(TAG, "Waiting for current installation");
try
{
if (!mEngineService.installVersion(mOpenCVersion))
{
Log.d(TAG, "OpenCV package was not installed!");
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.MARKET_ERROR);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.MARKET_ERROR);
}
else
{
Log.d(TAG, "Wating for package installation");
}
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
} catch (RemoteException e) {
e.printStackTrace();
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INIT_FAILED);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INIT_FAILED);
}
}
};
mUserAppCallback.onPackageInstall(InstallCallbackInterface.INSTALLATION_PROGRESS, WaitQuery);
}
return;
}
else
{
Log.d(TAG, "Trying to get library list");
mLibraryInstallationProgress = false;
String libs = mEngineService.getLibraryList(mOpenCVersion);
Log.d(TAG, "Library list: \"" + libs + "\"");
Log.d(TAG, "First attempt to load libs");
int status;
if (initOpenCVLibs(path, libs))
{
Log.d(TAG, "First attempt to load libs is OK");
String eol = System.getProperty("line.separator");
for (String str : Core.getBuildInformation().split(eol))
Log.i(TAG, str);
status = LoaderCallbackInterface.SUCCESS;
}
else
{
Log.d(TAG, "First attempt to load libs fails");
status = LoaderCallbackInterface.INIT_FAILED;
}
Log.d(TAG, "Init finished with status " + status);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(status);
}
}
catch (RemoteException e)
{
e.printStackTrace();
Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INIT_FAILED);
Log.d(TAG, "Unbind from service");
mAppContext.unbindService(mServiceConnection);
Log.d(TAG, "Calling using callback");
mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INIT_FAILED);
}
}
}
public void onServiceDisconnected(ComponentName className)
{
mEngineService = null;
}
};
private boolean loadLibrary(String AbsPath)
{
boolean result = true;
Log.d(TAG, "Trying to load library " + AbsPath);
try
{
System.load(AbsPath);
Log.d(TAG, "OpenCV libs init was ok!");
}
catch(UnsatisfiedLinkError e)
{
Log.d(TAG, "Cannot load library \"" + AbsPath + "\"");
e.printStackTrace();
result &= false;
}
return result;
}
private boolean initOpenCVLibs(String Path, String Libs)
{
Log.d(TAG, "Trying to init OpenCV libs");
if ((null != Path) && (Path.length() != 0))
{
boolean result = true;
if ((null != Libs) && (Libs.length() != 0))
{
Log.d(TAG, "Trying to load libs by dependency list");
StringTokenizer splitter = new StringTokenizer(Libs, ";");
while(splitter.hasMoreTokens())
{
String AbsLibraryPath = Path + File.separator + splitter.nextToken();
result &= loadLibrary(AbsLibraryPath);
}
}
else
{
// If the dependencies list is not defined or empty.
String AbsLibraryPath = Path + File.separator + "libopencv_java.so";
result &= loadLibrary(AbsLibraryPath);
}
return result;
}
else
{
Log.d(TAG, "Library path \"" + Path + "\" is empty");
return false;
}
}
}