Home | History | Annotate | Download | only in core
      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 
     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 
     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
     86     public void reset() {
     87         if (mHasResetFunction && !callNativeReset()) {
     88             throw new RuntimeException("Could not reset NativeProgram!");
     89         }
     90     }
     91 
     92     @Override
     93     protected void finalize() throws Throwable {
     94         tearDown();
     95     }
     96 
     97     @Override
     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
    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
    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 
    155     private native boolean allocate();
    156 
    157     private native boolean deallocate();
    158 
    159     private native boolean nativeInit();
    160 
    161     private native boolean openNativeLibrary(String libName);
    162 
    163     private native boolean bindInitFunction(String funcName);
    164     private native boolean bindSetValueFunction(String funcName);
    165     private native boolean bindGetValueFunction(String funcName);
    166     private native boolean bindProcessFunction(String funcName);
    167     private native boolean bindResetFunction(String funcName);
    168     private native boolean bindTeardownFunction(String funcName);
    169 
    170     private native boolean callNativeInit();
    171     private native boolean callNativeSetValue(String key, String value);
    172     private native String  callNativeGetValue(String key);
    173     private native boolean callNativeProcess(NativeFrame[] inputs, NativeFrame output);
    174     private native boolean callNativeReset();
    175     private native boolean callNativeTeardown();
    176 }
    177