1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 package android.filterfw.core;
19 
20 import android.filterfw.core.Frame;
21 import android.filterfw.core.Program;
22 
23 /**
24  * @hide
25  */
26 public class NativeProgram extends Program {
27 
28     private int nativeProgramId;
29     private boolean mHasInitFunction     = false;
30     private boolean mHasTeardownFunction = false;
31     private boolean mHasSetValueFunction = false;
32     private boolean mHasGetValueFunction = false;
33     private boolean mHasResetFunction = false;
34     private boolean mTornDown = false;
35 
NativeProgram(String nativeLibName, String nativeFunctionPrefix)36     public NativeProgram(String nativeLibName, String nativeFunctionPrefix) {
37         // Allocate the native instance
38         allocate();
39 
40         // Open the native library
41         String fullLibName = "lib" + nativeLibName + ".so";
42         if (!openNativeLibrary(fullLibName)) {
43             throw new RuntimeException("Could not find native library named '" + fullLibName + "' " +
44                                        "required for native program!");
45         }
46 
47         // Bind the native functions
48         String processFuncName = nativeFunctionPrefix + "_process";
49         if (!bindProcessFunction(processFuncName)) {
50             throw new RuntimeException("Could not find native program function name " +
51                                        processFuncName + " in library " + fullLibName + "! " +
52                                        "This function is required!");
53         }
54 
55         String initFuncName = nativeFunctionPrefix + "_init";
56         mHasInitFunction = bindInitFunction(initFuncName);
57 
58         String teardownFuncName = nativeFunctionPrefix + "_teardown";
59         mHasTeardownFunction = bindTeardownFunction(teardownFuncName);
60 
61         String setValueFuncName = nativeFunctionPrefix + "_setvalue";
62         mHasSetValueFunction = bindSetValueFunction(setValueFuncName);
63 
64         String getValueFuncName = nativeFunctionPrefix + "_getvalue";
65         mHasGetValueFunction = bindGetValueFunction(getValueFuncName);
66 
67         String resetFuncName = nativeFunctionPrefix + "_reset";
68         mHasResetFunction = bindResetFunction(resetFuncName);
69 
70         // Initialize the native code
71         if (mHasInitFunction && !callNativeInit()) {
72             throw new RuntimeException("Could not initialize NativeProgram!");
73         }
74     }
75 
tearDown()76     public void tearDown() {
77         if (mTornDown) return;
78         if (mHasTeardownFunction && !callNativeTeardown()) {
79             throw new RuntimeException("Could not tear down NativeProgram!");
80         }
81         deallocate();
82         mTornDown = true;
83     }
84 
85     @Override
reset()86     public void reset() {
87         if (mHasResetFunction && !callNativeReset()) {
88             throw new RuntimeException("Could not reset NativeProgram!");
89         }
90     }
91 
92     @Override
finalize()93     protected void finalize() throws Throwable {
94         tearDown();
95     }
96 
97     @Override
process(Frame[] inputs, Frame output)98     public void process(Frame[] inputs, Frame output) {
99         if (mTornDown) {
100             throw new RuntimeException("NativeProgram already torn down!");
101         }
102         NativeFrame[] nativeInputs = new NativeFrame[inputs.length];
103         for (int i = 0; i < inputs.length; ++i) {
104             if (inputs[i] == null || inputs[i] instanceof NativeFrame) {
105                 nativeInputs[i] = (NativeFrame)inputs[i];
106             } else {
107                 throw new RuntimeException("NativeProgram got non-native frame as input "+ i +"!");
108             }
109         }
110 
111         // Get the native output frame
112         NativeFrame nativeOutput = null;
113         if (output == null || output instanceof NativeFrame) {
114             nativeOutput = (NativeFrame)output;
115         } else {
116             throw new RuntimeException("NativeProgram got non-native output frame!");
117         }
118 
119         // Process!
120         if (!callNativeProcess(nativeInputs, nativeOutput)) {
121             throw new RuntimeException("Calling native process() caused error!");
122         }
123     }
124 
125     @Override
setHostValue(String variableName, Object value)126     public void setHostValue(String variableName, Object value) {
127         if (mTornDown) {
128             throw new RuntimeException("NativeProgram already torn down!");
129         }
130         if (!mHasSetValueFunction) {
131             throw new RuntimeException("Attempting to set native variable, but native code does not " +
132                                        "define native setvalue function!");
133         }
134         if (!callNativeSetValue(variableName, value.toString())) {
135             throw new RuntimeException("Error setting native value for variable '" + variableName + "'!");
136         }
137     }
138 
139     @Override
getHostValue(String variableName)140     public Object getHostValue(String variableName) {
141         if (mTornDown) {
142             throw new RuntimeException("NativeProgram already torn down!");
143         }
144         if (!mHasGetValueFunction) {
145             throw new RuntimeException("Attempting to get native variable, but native code does not " +
146                                        "define native getvalue function!");
147         }
148         return callNativeGetValue(variableName);
149     }
150 
151     static {
152         System.loadLibrary("filterfw");
153     }
154 
allocate()155     private native boolean allocate();
156 
deallocate()157     private native boolean deallocate();
158 
nativeInit()159     private native boolean nativeInit();
160 
openNativeLibrary(String libName)161     private native boolean openNativeLibrary(String libName);
162 
bindInitFunction(String funcName)163     private native boolean bindInitFunction(String funcName);
bindSetValueFunction(String funcName)164     private native boolean bindSetValueFunction(String funcName);
bindGetValueFunction(String funcName)165     private native boolean bindGetValueFunction(String funcName);
bindProcessFunction(String funcName)166     private native boolean bindProcessFunction(String funcName);
bindResetFunction(String funcName)167     private native boolean bindResetFunction(String funcName);
bindTeardownFunction(String funcName)168     private native boolean bindTeardownFunction(String funcName);
169 
callNativeInit()170     private native boolean callNativeInit();
callNativeSetValue(String key, String value)171     private native boolean callNativeSetValue(String key, String value);
callNativeGetValue(String key)172     private native String  callNativeGetValue(String key);
callNativeProcess(NativeFrame[] inputs, NativeFrame output)173     private native boolean callNativeProcess(NativeFrame[] inputs, NativeFrame output);
callNativeReset()174     private native boolean callNativeReset();
callNativeTeardown()175     private native boolean callNativeTeardown();
176 }
177