1package org.opencv.android; 2 3import java.io.File; 4import java.util.StringTokenizer; 5 6import org.opencv.core.Core; 7import org.opencv.engine.OpenCVEngineInterface; 8 9import android.content.ComponentName; 10import android.content.Context; 11import android.content.Intent; 12import android.content.ServiceConnection; 13import android.net.Uri; 14import android.os.IBinder; 15import android.os.RemoteException; 16import android.util.Log; 17 18class AsyncServiceHelper 19{ 20 public static boolean initOpenCV(String Version, final Context AppContext, 21 final LoaderCallbackInterface Callback) 22 { 23 AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback); 24 Intent intent = new Intent("org.opencv.engine.BIND"); 25 intent.setPackage("org.opencv.engine"); 26 if (AppContext.bindService(intent, helper.mServiceConnection, Context.BIND_AUTO_CREATE)) 27 { 28 return true; 29 } 30 else 31 { 32 AppContext.unbindService(helper.mServiceConnection); 33 InstallService(AppContext, Callback); 34 return false; 35 } 36 } 37 38 protected AsyncServiceHelper(String Version, Context AppContext, LoaderCallbackInterface Callback) 39 { 40 mOpenCVersion = Version; 41 mUserAppCallback = Callback; 42 mAppContext = AppContext; 43 } 44 45 protected static final String TAG = "OpenCVManager/Helper"; 46 protected static final int MINIMUM_ENGINE_VERSION = 2; 47 protected OpenCVEngineInterface mEngineService; 48 protected LoaderCallbackInterface mUserAppCallback; 49 protected String mOpenCVersion; 50 protected Context mAppContext; 51 protected static boolean mServiceInstallationProgress = false; 52 protected static boolean mLibraryInstallationProgress = false; 53 54 protected static boolean InstallServiceQuiet(Context context) 55 { 56 boolean result = true; 57 try 58 { 59 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(OPEN_CV_SERVICE_URL)); 60 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 61 context.startActivity(intent); 62 } 63 catch(Exception e) 64 { 65 result = false; 66 } 67 68 return result; 69 } 70 71 protected static void InstallService(final Context AppContext, final LoaderCallbackInterface Callback) 72 { 73 if (!mServiceInstallationProgress) 74 { 75 Log.d(TAG, "Request new service installation"); 76 InstallCallbackInterface InstallQuery = new InstallCallbackInterface() { 77 private LoaderCallbackInterface mUserAppCallback = Callback; 78 public String getPackageName() 79 { 80 return "OpenCV Manager"; 81 } 82 public void install() { 83 Log.d(TAG, "Trying to install OpenCV Manager via Google Play"); 84 85 boolean result = InstallServiceQuiet(AppContext); 86 if (result) 87 { 88 mServiceInstallationProgress = true; 89 Log.d(TAG, "Package installation started"); 90 } 91 else 92 { 93 Log.d(TAG, "OpenCV package was not installed!"); 94 int Status = LoaderCallbackInterface.MARKET_ERROR; 95 Log.d(TAG, "Init finished with status " + Status); 96 Log.d(TAG, "Unbind from service"); 97 Log.d(TAG, "Calling using callback"); 98 mUserAppCallback.onManagerConnected(Status); 99 } 100 } 101 102 public void cancel() 103 { 104 Log.d(TAG, "OpenCV library installation was canceled"); 105 int Status = LoaderCallbackInterface.INSTALL_CANCELED; 106 Log.d(TAG, "Init finished with status " + Status); 107 Log.d(TAG, "Calling using callback"); 108 mUserAppCallback.onManagerConnected(Status); 109 } 110 111 public void wait_install() 112 { 113 Log.e(TAG, "Instalation was not started! Nothing to wait!"); 114 } 115 }; 116 117 Callback.onPackageInstall(InstallCallbackInterface.NEW_INSTALLATION, InstallQuery); 118 } 119 else 120 { 121 Log.d(TAG, "Waiting current installation process"); 122 InstallCallbackInterface WaitQuery = new InstallCallbackInterface() { 123 private LoaderCallbackInterface mUserAppCallback = Callback; 124 public String getPackageName() 125 { 126 return "OpenCV Manager"; 127 } 128 public void install() 129 { 130 Log.e(TAG, "Nothing to install we just wait current installation"); 131 } 132 public void cancel() 133 { 134 Log.d(TAG, "Wating for OpenCV canceled by user"); 135 mServiceInstallationProgress = false; 136 int Status = LoaderCallbackInterface.INSTALL_CANCELED; 137 Log.d(TAG, "Init finished with status " + Status); 138 Log.d(TAG, "Calling using callback"); 139 mUserAppCallback.onManagerConnected(Status); 140 } 141 public void wait_install() 142 { 143 InstallServiceQuiet(AppContext); 144 } 145 }; 146 147 Callback.onPackageInstall(InstallCallbackInterface.INSTALLATION_PROGRESS, WaitQuery); 148 } 149 } 150 151 /** 152 * URL of OpenCV Manager page on Google Play Market. 153 */ 154 protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine"; 155 156 protected ServiceConnection mServiceConnection = new ServiceConnection() 157 { 158 public void onServiceConnected(ComponentName className, IBinder service) 159 { 160 Log.d(TAG, "Service connection created"); 161 mEngineService = OpenCVEngineInterface.Stub.asInterface(service); 162 if (null == mEngineService) 163 { 164 Log.d(TAG, "OpenCV Manager Service connection fails. May be service was not installed?"); 165 InstallService(mAppContext, mUserAppCallback); 166 } 167 else 168 { 169 mServiceInstallationProgress = false; 170 try 171 { 172 if (mEngineService.getEngineVersion() < MINIMUM_ENGINE_VERSION) 173 { 174 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INCOMPATIBLE_MANAGER_VERSION); 175 Log.d(TAG, "Unbind from service"); 176 mAppContext.unbindService(mServiceConnection); 177 Log.d(TAG, "Calling using callback"); 178 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INCOMPATIBLE_MANAGER_VERSION); 179 return; 180 } 181 182 Log.d(TAG, "Trying to get library path"); 183 String path = mEngineService.getLibPathByVersion(mOpenCVersion); 184 if ((null == path) || (path.length() == 0)) 185 { 186 if (!mLibraryInstallationProgress) 187 { 188 InstallCallbackInterface InstallQuery = new InstallCallbackInterface() { 189 public String getPackageName() 190 { 191 return "OpenCV library"; 192 } 193 public void install() { 194 Log.d(TAG, "Trying to install OpenCV lib via Google Play"); 195 try 196 { 197 if (mEngineService.installVersion(mOpenCVersion)) 198 { 199 mLibraryInstallationProgress = true; 200 Log.d(TAG, "Package installation statred"); 201 Log.d(TAG, "Unbind from service"); 202 mAppContext.unbindService(mServiceConnection); 203 } 204 else 205 { 206 Log.d(TAG, "OpenCV package was not installed!"); 207 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.MARKET_ERROR); 208 Log.d(TAG, "Unbind from service"); 209 mAppContext.unbindService(mServiceConnection); 210 Log.d(TAG, "Calling using callback"); 211 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.MARKET_ERROR); 212 } 213 } catch (RemoteException e) { 214 e.printStackTrace();; 215 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INIT_FAILED); 216 Log.d(TAG, "Unbind from service"); 217 mAppContext.unbindService(mServiceConnection); 218 Log.d(TAG, "Calling using callback"); 219 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INIT_FAILED); 220 } 221 } 222 public void cancel() { 223 Log.d(TAG, "OpenCV library installation was canceled"); 224 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INSTALL_CANCELED); 225 Log.d(TAG, "Unbind from service"); 226 mAppContext.unbindService(mServiceConnection); 227 Log.d(TAG, "Calling using callback"); 228 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INSTALL_CANCELED); 229 } 230 public void wait_install() { 231 Log.e(TAG, "Instalation was not started! Nothing to wait!"); 232 } 233 }; 234 235 mUserAppCallback.onPackageInstall(InstallCallbackInterface.NEW_INSTALLATION, InstallQuery); 236 } 237 else 238 { 239 InstallCallbackInterface WaitQuery = new InstallCallbackInterface() { 240 public String getPackageName() 241 { 242 return "OpenCV library"; 243 } 244 245 public void install() { 246 Log.e(TAG, "Nothing to install we just wait current installation"); 247 } 248 public void cancel() 249 { 250 Log.d(TAG, "OpenCV library installation was canceled"); 251 mLibraryInstallationProgress = false; 252 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INSTALL_CANCELED); 253 Log.d(TAG, "Unbind from service"); 254 mAppContext.unbindService(mServiceConnection); 255 Log.d(TAG, "Calling using callback"); 256 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INSTALL_CANCELED); 257 } 258 public void wait_install() { 259 Log.d(TAG, "Waiting for current installation"); 260 try 261 { 262 if (!mEngineService.installVersion(mOpenCVersion)) 263 { 264 Log.d(TAG, "OpenCV package was not installed!"); 265 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.MARKET_ERROR); 266 Log.d(TAG, "Calling using callback"); 267 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.MARKET_ERROR); 268 } 269 else 270 { 271 Log.d(TAG, "Wating for package installation"); 272 } 273 274 Log.d(TAG, "Unbind from service"); 275 mAppContext.unbindService(mServiceConnection); 276 277 } catch (RemoteException e) { 278 e.printStackTrace(); 279 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INIT_FAILED); 280 Log.d(TAG, "Unbind from service"); 281 mAppContext.unbindService(mServiceConnection); 282 Log.d(TAG, "Calling using callback"); 283 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INIT_FAILED); 284 } 285 } 286 }; 287 288 mUserAppCallback.onPackageInstall(InstallCallbackInterface.INSTALLATION_PROGRESS, WaitQuery); 289 } 290 return; 291 } 292 else 293 { 294 Log.d(TAG, "Trying to get library list"); 295 mLibraryInstallationProgress = false; 296 String libs = mEngineService.getLibraryList(mOpenCVersion); 297 Log.d(TAG, "Library list: \"" + libs + "\""); 298 Log.d(TAG, "First attempt to load libs"); 299 int status; 300 if (initOpenCVLibs(path, libs)) 301 { 302 Log.d(TAG, "First attempt to load libs is OK"); 303 String eol = System.getProperty("line.separator"); 304 for (String str : Core.getBuildInformation().split(eol)) 305 Log.i(TAG, str); 306 307 status = LoaderCallbackInterface.SUCCESS; 308 } 309 else 310 { 311 Log.d(TAG, "First attempt to load libs fails"); 312 status = LoaderCallbackInterface.INIT_FAILED; 313 } 314 315 Log.d(TAG, "Init finished with status " + status); 316 Log.d(TAG, "Unbind from service"); 317 mAppContext.unbindService(mServiceConnection); 318 Log.d(TAG, "Calling using callback"); 319 mUserAppCallback.onManagerConnected(status); 320 } 321 } 322 catch (RemoteException e) 323 { 324 e.printStackTrace(); 325 Log.d(TAG, "Init finished with status " + LoaderCallbackInterface.INIT_FAILED); 326 Log.d(TAG, "Unbind from service"); 327 mAppContext.unbindService(mServiceConnection); 328 Log.d(TAG, "Calling using callback"); 329 mUserAppCallback.onManagerConnected(LoaderCallbackInterface.INIT_FAILED); 330 } 331 } 332 } 333 334 public void onServiceDisconnected(ComponentName className) 335 { 336 mEngineService = null; 337 } 338 }; 339 340 private boolean loadLibrary(String AbsPath) 341 { 342 boolean result = true; 343 344 Log.d(TAG, "Trying to load library " + AbsPath); 345 try 346 { 347 System.load(AbsPath); 348 Log.d(TAG, "OpenCV libs init was ok!"); 349 } 350 catch(UnsatisfiedLinkError e) 351 { 352 Log.d(TAG, "Cannot load library \"" + AbsPath + "\""); 353 e.printStackTrace(); 354 result &= false; 355 } 356 357 return result; 358 } 359 360 private boolean initOpenCVLibs(String Path, String Libs) 361 { 362 Log.d(TAG, "Trying to init OpenCV libs"); 363 if ((null != Path) && (Path.length() != 0)) 364 { 365 boolean result = true; 366 if ((null != Libs) && (Libs.length() != 0)) 367 { 368 Log.d(TAG, "Trying to load libs by dependency list"); 369 StringTokenizer splitter = new StringTokenizer(Libs, ";"); 370 while(splitter.hasMoreTokens()) 371 { 372 String AbsLibraryPath = Path + File.separator + splitter.nextToken(); 373 result &= loadLibrary(AbsLibraryPath); 374 } 375 } 376 else 377 { 378 // If the dependencies list is not defined or empty. 379 String AbsLibraryPath = Path + File.separator + "libopencv_java.so"; 380 result &= loadLibrary(AbsLibraryPath); 381 } 382 383 return result; 384 } 385 else 386 { 387 Log.d(TAG, "Library path \"" + Path + "\" is empty"); 388 return false; 389 } 390 } 391} 392