1c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu/*
2c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * Copyright (C) 2013 The Android Open Source Project
3c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu *
4c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * Licensed under the Apache License, Version 2.0 (the "License");
5c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * you may not use this file except in compliance with the License.
6c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * You may obtain a copy of the License at
7c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu *
8c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu *      http://www.apache.org/licenses/LICENSE-2.0
9c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu *
10c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * Unless required by applicable law or agreed to in writing, software
11c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * distributed under the License is distributed on an "AS IS" BASIS,
12c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * See the License for the specific language governing permissions and
14c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * limitations under the License.
15c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu */
16c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xupackage com.android.cts.verifier.sensors.helpers;
17c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
18341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xuimport android.content.ComponentName;
19c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xuimport android.content.Context;
20341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xuimport android.content.Intent;
21341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xuimport android.content.ServiceConnection;
22341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xuimport android.os.IBinder;
23c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xuimport android.util.Log;
24c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
25c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xuimport org.opencv.android.BaseLoaderCallback;
26c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xuimport org.opencv.android.LoaderCallbackInterface;
27c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xuimport org.opencv.android.OpenCVLoader;
28c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
29c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xuimport java.util.concurrent.CountDownLatch;
30341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xuimport java.util.concurrent.TimeUnit;
31c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
32c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu/**
33c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu * OpenCV library loader class
34c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu */
35c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xupublic class OpenCVLibrary {
36c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
37341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    private final static String TAG = "OpenCVLibraryProbe";
38341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    private final static int ASYNC_LOAD_TIMEOUT_SEC = 30;
39341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    private static boolean sLoaded = false;
40c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
41c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu    /**
42c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu     * Load OpenCV Library in async mode
43341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     *
44341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     * @param context Activity context.
45341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     * @param allowStatic Allow trying load from local package.
46341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     * @param allowInstall Allow installing package from play store.
47341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     *
48341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     * @return if load succeed return true. Return false otherwise.
49c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu     */
50341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    public static boolean load(Context context,
51341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            boolean allowLocal, boolean allowPackage, boolean allowInstall) {
52c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu        // only need to load once
53341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        if (!sLoaded) {
54341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            // Try static load first
55341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            if (allowLocal && OpenCVLoader.initDebug()) {
56341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                sLoaded = true;
57341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            } else if (allowPackage) {
58341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                if (allowInstall || probePackage(context)) {
59341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                    final CountDownLatch done = new CountDownLatch(1);
60341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                    // Load the library through async loader
61341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, context,
62341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                            new BaseLoaderCallback(context) {
63341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                @Override
64341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                public void onManagerConnected(int status) {
65341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                    Log.v(TAG, "New Loading status: " + status);
66341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                    switch (status) {
67341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                        case LoaderCallbackInterface.SUCCESS: {
68341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                            sLoaded = true;
69341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                        }
70341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                        break;
71341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                        default: {
72341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                            Log.e(TAG, "Connecting OpenCV Manager failed");
73341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                        }
74341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                        break;
75341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                    }
76341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                    done.countDown();
77341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                                }
78341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                            });
79341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                    try {
80341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                        if (!done.await(ASYNC_LOAD_TIMEOUT_SEC, TimeUnit.SECONDS)) {
81341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                            Log.e(TAG, "Time out when attempt async load");
82c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu                        }
83341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                    } catch (InterruptedException e) {
84341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                        Thread.currentThread().interrupt();
85c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu                    }
86341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                }
87341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            }
88341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        }
89341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        return sLoaded;
90c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu    }
91c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu
92c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu    /**
93c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu     * Test if the library is loaded
94c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu     * @return a boolean indicates whether the OpenCV library is loaded.
95c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu     */
96c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu    public static boolean isLoaded() {
97341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        return sLoaded;
98341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    }
99341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu
100341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    /**
101341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     * Probe if the OpenCV Manager package is installed
102341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     *
103341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     * @return a boolean indicate wheather OpenCV Manager is installed
104341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu     */
105341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu    private static boolean probePackage(Context context) {
106341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        Intent intent = new Intent("org.opencv.engine.BIND");
107341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        intent.setPackage("org.opencv.engine");
108341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu
109341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        ServiceConnection conn = new ServiceConnection() {
110341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            @Override
111341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            public void onServiceConnected(ComponentName className, IBinder service) {
112341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                // Do nothing
113341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            }
114341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            @Override
115341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            public void onServiceDisconnected(ComponentName className) {
116341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                // Do nothing
117341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            }
118341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        };
119341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu
120341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        boolean ret = false;
121341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        try {
122341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            if (context.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
123341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu                ret = true;
124341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            }
125341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        } finally {
126341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu            context.unbindService(conn);
127341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        }
128341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu
129341dc36e3d9d1259d8023d694902b8c58d9b49caPeng Xu        return ret;
130c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu    }
131c14f012e99fb84d5f17bff5b21ba6f4926db8d24Peng Xu}
132