// // Copyright 2017, 2018 Filippo "Fil" Bergamo // // This file is part of RepWifiApp. // // RepWifiApp is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // RepWifiApp is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with RepWifiApp. If not, see . // // ******************************************************************** package fil.libre.repwifiapp.fwproxies; import fil.libre.repwifiapp.helpers.Logger; import java.lang.reflect.Constructor; /** * Provides a base class for creating "proxy" classes that wrap up classes from * the Android Application Framework via reflection, exposing them outside the * framework itself. */ public abstract class FrameworkProxy { protected Object inner; protected abstract String getInnerClassName(); protected static String getStaticInnerClassName() { return "Object"; } protected static Class getClassFromName(String className) { try { return Class.forName(className); } catch (ClassNotFoundException e) { Logger.logError(null, e); return null; } } protected Class getInnerClass() { return getClassFromName(getInnerClassName()); } protected Class[] getTypesArray(Class... args) { Class[] types = new Class[args.length]; for (int i = 0; i < args.length; i++) { types[i] = args[i]; } return types; } protected Object createInnerObject(Class argType, Object arg) { return createInnerObject(getTypesArray(argType), arg); } protected Object createInnerObject(Class[] argumentTypes, Object... args) { try { Class cls = getClassFromName(getInnerClassName()); Constructor c = cls.getConstructor(argumentTypes); this.inner = c.newInstance(getRealArgs(args)); return this.inner; } catch (Exception e) { Logger.logError("Exception while creating inner object via reflection.", e); return null; } } protected Object invokeMethodGetResult(String methodName, Class argumentType, Object arg) { return invokeMethodGetResult(methodName, getTypesArray(argumentType), arg); } protected Object invokeMethodGetResult(String methodName, Class[] argumentTypes, Object... args) { try { return getClassFromName(getInnerClassName()).getMethod(methodName, argumentTypes) .invoke(inner, getRealArgs(args)); } catch (Exception e) { Logger.logError("Exception while invoking method via reflection.", e); return null; } } protected void invokeMethod(String methodName, Class argumentType, Object arg) { invokeMethod(methodName, getTypesArray(argumentType), arg); } protected void invokeMethod(String methodName, Class[] argumentTypes, Object... args) { try { getClassFromName(getInnerClassName()).getMethod(methodName, argumentTypes).invoke( inner, getRealArgs(args)); } catch (Exception e) { Logger.logError("Exception while invoking method via reflection.", e); } } private Object[] getRealArgs(Object[] args) { if (args == null || args.length == 0) { return new Object[] {}; } // if the object is just a proxy, use the inner object as an argument to // the call. for (int i = 0; i < args.length; i++) { if (args[i] instanceof FrameworkProxy) { args[i] = ((FrameworkProxy) args[i]).inner; } } return args; } }