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