aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/fil/libre/repwifiapp/fwproxies
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/fil/libre/repwifiapp/fwproxies')
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/ConnectivityManagerProxy.java98
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/FrameworkProxy.java126
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/LinkAddressProxy.java61
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/LinkPropertiesProxy.java90
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/NetworkCapabilitiesProxy.java90
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/NetworkInfoProxy.java102
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/RepWifiNetworkAgent.java581
-rw-r--r--app/src/fil/libre/repwifiapp/fwproxies/RouteInfoProxy.java59
8 files changed, 1207 insertions, 0 deletions
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/ConnectivityManagerProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/ConnectivityManagerProxy.java
new file mode 100644
index 0000000..f2e7de7
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/ConnectivityManagerProxy.java
@@ -0,0 +1,98 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work, inspired by the original class definition:
+// "android.net.ConnectivityManager.java" as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package fil.libre.repwifiapp.fwproxies;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Messenger;
+
+public class ConnectivityManagerProxy extends FrameworkProxy {
+
+ private Context currentContext;
+
+ public ConnectivityManagerProxy(Context context) {
+ currentContext = context;
+ init();
+ }
+
+ @Override
+ protected String getInnerClassName() {
+ return ConnectivityManager.class.getCanonicalName();
+ }
+
+
+ public int registerNetworkAgent(Messenger msgr, NetworkInfoProxy ni,
+ LinkPropertiesProxy lp, NetworkCapabilitiesProxy nc, int score){
+
+ Class<?>[] types = getTypesArray(Messenger.class,
+ NetworkInfo.class,
+ getClassFromName(LinkPropertiesProxy.getStaticInnerClassName()),
+ getClassFromName(NetworkCapabilitiesProxy.getStaticInnerClassName()),
+ int.class,
+ getClassFromName("android.net.NetworkMisc"));
+
+ return (Integer)invokeMethodGetResult("registerNetworkAgent",types, msgr, ni.getNetworkInfo(), lp, nc, score, null);
+
+ }
+
+/* public boolean isWifiConnected(){
+
+ init();
+ ConnectivityManager cm = (ConnectivityManager)inner;
+
+ NetworkInfo i = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ if (i == null){
+ return false;
+ } else {
+ return i.isConnected();
+ }
+
+ }*/
+
+ private void init(){
+
+ if (this.inner == null){
+ this.inner = currentContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+
+ }
+
+
+}
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/FrameworkProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/FrameworkProxy.java
new file mode 100644
index 0000000..a468a1c
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/FrameworkProxy.java
@@ -0,0 +1,126 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+
+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;
+
+ }
+
+} \ No newline at end of file
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/LinkAddressProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/LinkAddressProxy.java
new file mode 100644
index 0000000..5fcd211
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/LinkAddressProxy.java
@@ -0,0 +1,61 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work, inspired by the original class definition:
+// "android.net.LinkAddress.java" as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package fil.libre.repwifiapp.fwproxies;
+
+import java.net.InetAddress;
+
+
+public class LinkAddressProxy extends FrameworkProxy {
+
+ @Override
+ protected String getInnerClassName() {
+ return "android.net.LinkAddress";
+ }
+
+ public LinkAddressProxy(String ipAndMask){
+ createInnerObject(String.class, ipAndMask);
+ }
+
+ public LinkAddressProxy(InetAddress address, int mask){
+ createInnerObject(getTypesArray(InetAddress.class, int.class), address, mask);
+ }
+
+
+}
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/LinkPropertiesProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/LinkPropertiesProxy.java
new file mode 100644
index 0000000..4bfeeaa
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/LinkPropertiesProxy.java
@@ -0,0 +1,90 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work, inspired by the original class definition:
+// "android.net.LinkProperties.java" as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package fil.libre.repwifiapp.fwproxies;
+
+import java.net.InetAddress;
+
+
+public class LinkPropertiesProxy extends FrameworkProxy{
+
+ @Override
+ protected String getInnerClassName(){
+ return "android.net.LinkProperties";
+ }
+
+ public LinkPropertiesProxy(){
+ createInnerObject(null);
+ }
+
+ public LinkPropertiesProxy(LinkPropertiesProxy lp){
+ createInnerObject(getInnerClass(), lp.inner);
+ }
+
+ public void setInterfaceName(String iface) {
+ invokeMethod("setInterfaceName", String.class , iface);
+ }
+
+ public boolean addRoute(RouteInfoProxy route) {
+ if (route == null){
+ return false;
+ }
+ return (Boolean)invokeMethodGetResult("addRoute", route.getInnerClass(), route);
+ }
+
+ public boolean addLinkAddress(LinkAddressProxy address) {
+ if (address == null){
+ return false;
+ }
+ return (Boolean)invokeMethodGetResult("addLinkAddress",address.getInnerClass(), address);
+ }
+
+ public boolean addDnsServer(InetAddress dnsServer) {
+ if (dnsServer == null){
+ return false;
+ }
+ return (Boolean)invokeMethodGetResult("addDnsServer", InetAddress.class, dnsServer);
+ }
+
+ protected static String getStaticInnerClassName(){
+ return "android.net.LinkProperties";
+ }
+
+
+}
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/NetworkCapabilitiesProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/NetworkCapabilitiesProxy.java
new file mode 100644
index 0000000..f66bebd
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/NetworkCapabilitiesProxy.java
@@ -0,0 +1,90 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work, inspired by the original class definition:
+// "android.net.NetworkCapabilities.java" as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package fil.libre.repwifiapp.fwproxies;
+
+
+public class NetworkCapabilitiesProxy extends FrameworkProxy{
+
+ public static final int NET_CAPABILITY_MMS = 0;
+ public static final int NET_CAPABILITY_SUPL = 1;
+ public static final int NET_CAPABILITY_DUN = 2;
+ public static final int NET_CAPABILITY_FOTA = 3;
+ public static final int NET_CAPABILITY_IMS = 4;
+ public static final int NET_CAPABILITY_CBS = 5;
+ public static final int NET_CAPABILITY_WIFI_P2P = 6;
+ public static final int NET_CAPABILITY_IA = 7;
+ public static final int NET_CAPABILITY_RCS = 8;
+ public static final int NET_CAPABILITY_XCAP = 9;
+ public static final int NET_CAPABILITY_EIMS = 10;
+ public static final int NET_CAPABILITY_NOT_METERED = 11;
+ public static final int NET_CAPABILITY_INTERNET = 12;
+ public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
+ public static final int NET_CAPABILITY_TRUSTED = 14;
+ public static final int NET_CAPABILITY_NOT_VPN = 15;
+ public static final int NET_CAPABILITY_VALIDATED = 16;
+ public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17;
+
+ public NetworkCapabilitiesProxy(){
+ createInnerObject(null);
+ }
+
+ public NetworkCapabilitiesProxy(NetworkCapabilitiesProxy nc){
+ createInnerObject(getInnerClass(), nc.inner);
+ }
+
+ public void addCapability(int capability) {
+ invokeMethod("addCapability", new Class<?>[]{int.class}, capability);
+ }
+
+ public void removeCapability(int capability) {
+ invokeMethod("removeCapability", new Class<?>[]{int.class}, capability);
+ }
+
+ @Override
+ protected String getInnerClassName() {
+ return "android.net.NetworkCapabilities";
+ }
+
+ protected static String getStaticInnerClassName(){
+ return "android.net.NetworkCapabilities";
+ }
+
+}
+
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/NetworkInfoProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/NetworkInfoProxy.java
new file mode 100644
index 0000000..0537451
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/NetworkInfoProxy.java
@@ -0,0 +1,102 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work of the original class definition:
+// "android.net.NetworkInfo" as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package fil.libre.repwifiapp.fwproxies;
+
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+
+public class NetworkInfoProxy extends FrameworkProxy {
+
+ @Override
+ protected String getInnerClassName() {
+ return "android.net.NetworkInfo";
+ }
+
+ public NetworkInfoProxy(int type, int subtype, String typeName, String subtypeName){
+ createInnerObject(new Class<?>[]{int.class, int.class, String.class, String.class}, type, subtype, typeName, subtypeName);
+ }
+
+ public NetworkInfoProxy(NetworkInfo source){
+ createInnerObject(new Class<?>[]{NetworkInfo.class}, source);
+ }
+
+ public static NetworkInfoProxy getForWifi(){
+ return new NetworkInfoProxy(ConnectivityManager.TYPE_WIFI,0, "WIFI", "");
+ }
+
+ public NetworkInfo getNetworkInfo(){
+ if (inner == null){
+ return null;
+ }
+ return (NetworkInfo)inner;
+ }
+
+ public void setType(int type) {
+ invokeMethod("setType", new Class<?>[]{int.class}, type);
+ }
+
+ public void setSubtype(int subtype, String subtypeName) {
+ invokeMethod("setSubType", new Class<?>[]{int.class, String.class}, subtype, subtypeName);
+ }
+
+ public void setIsAvailable(boolean isAvailable) {
+ invokeMethod("setIsAvailable", new Class<?>[]{boolean.class}, isAvailable);
+ }
+
+ public void setFailover(boolean isFailover) {
+ invokeMethod("setFailover", new Class<?>[]{boolean.class}, isFailover);
+ }
+
+
+ public void setRoaming(boolean isRoaming) {
+ invokeMethod("setRoaming", new Class<?>[]{boolean.class}, isRoaming);
+ }
+
+ public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
+ invokeMethod("setDetailedState", new Class<?>[]{DetailedState.class, String.class, String.class}, detailedState, reason, extraInfo);
+ }
+
+ public void setExtraInfo(String extraInfo) {
+ invokeMethod("setExtraInfo", new Class<?>[]{String.class}, extraInfo);
+ }
+
+
+}
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/RepWifiNetworkAgent.java b/app/src/fil/libre/repwifiapp/fwproxies/RepWifiNetworkAgent.java
new file mode 100644
index 0000000..bab5c5d
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/RepWifiNetworkAgent.java
@@ -0,0 +1,581 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work, inspired by the original class definition:
+// "com.android.server.wifi.WifiStateMachine$WifiNetworkAgent.java"
+// as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package fil.libre.repwifiapp.fwproxies;
+
+import android.content.Context;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class RepWifiNetworkAgent extends Handler {
+
+ public final int netId;
+
+ private Messenger myMessenger = null;
+
+ private volatile AsyncChannelProxy mAsyncChannel;
+ private final String LOG_TAG;
+ private static final boolean DBG = true;
+ private static final boolean VDBG = true;
+ private final Context mContext;
+ private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>();
+ private volatile long mLastBwRefreshTime = 0;
+ private static final long BW_REFRESH_MIN_WIN_MS = 500;
+ private boolean mPollLceScheduled = false;
+ private AtomicBoolean mPollLcePending = new AtomicBoolean(false);
+
+ /* as in com.android.internal.util.Protocol.BASE_NETWORK_AGENT; */
+ private static final int BASE = 0x00081000;
+
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to inform it of
+ * suspected connectivity problems on its network. The NetworkAgent
+ * should take steps to verify and correct connectivity.
+ */
+ public static final int CMD_SUSPECT_BAD = BASE;
+
+ /**
+ * Sent by the NetworkAgent (note the EVENT vs CMD prefix) to
+ * ConnectivityService to pass the current NetworkInfo (connection state).
+ * Sent when the NetworkInfo changes, mainly due to change of state.
+ * obj = NetworkInfo
+ */
+ public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to pass the current
+ * NetworkCapabilties.
+ * obj = NetworkCapabilities
+ */
+ public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to pass the current
+ * NetworkProperties.
+ * obj = NetworkProperties
+ */
+ public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
+
+ public static final int WIFI_BASE_SCORE = 60;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to pass the current
+ * network score.
+ * obj = network score Integer
+ */
+ public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to add new UID ranges
+ * to be forced into this Network. For VPNs only.
+ * obj = UidRange[] to forward
+ */
+ public static final int EVENT_UID_RANGES_ADDED = BASE + 5;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to remove UID ranges
+ * from being forced into this Network. For VPNs only.
+ * obj = UidRange[] to stop forwarding
+ */
+ public static final int EVENT_UID_RANGES_REMOVED = BASE + 6;
+
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to inform the agent of
+ * the
+ * networks status - whether we could use the network or could not, due to
+ * either a bad network configuration (no internet link) or captive portal.
+ *
+ * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK}
+ */
+ public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
+
+ public static final int VALID_NETWORK = 1;
+ public static final int INVALID_NETWORK = 2;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to indicate this network
+ * was
+ * explicitly selected. This should be sent before the NetworkInfo is marked
+ * CONNECTED so it can be given special treatment at that time.
+ *
+ * obj = boolean indicating whether to use this network even if unvalidated
+ */
+ public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8;
+
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to inform the agent of
+ * whether the network should in the future be used even if not validated.
+ * This decision is made by the user, but it is the network transport's
+ * responsibility to remember it.
+ *
+ * arg1 = 1 if true, 0 if false
+ */
+ public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9;
+
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to inform the agent to
+ * pull
+ * the underlying network connection for updated bandwidth information.
+ */
+ public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10;
+
+ /**
+ * Sent by ConnectivityService to the NetworkAgent to request that the
+ * specified packet be sent
+ * periodically on the given interval.
+ *
+ * arg1 = the slot number of the keepalive to start
+ * arg2 = interval in seconds
+ * obj = KeepalivePacketData object describing the data to be sent
+ *
+ * Also used internally by ConnectivityService / KeepaliveTracker, with
+ * different semantics.
+ */
+ public static final int CMD_START_PACKET_KEEPALIVE = BASE + 11;
+
+ /**
+ * Requests that the specified keepalive packet be stopped.
+ *
+ * arg1 = slot number of the keepalive to stop.
+ *
+ * Also used internally by ConnectivityService / KeepaliveTracker, with
+ * different semantics.
+ */
+ public static final int CMD_STOP_PACKET_KEEPALIVE = BASE + 12;
+
+ /**
+ * Sent by the NetworkAgent to ConnectivityService to provide status on a
+ * packet keepalive
+ * request. This may either be the reply to a CMD_START_PACKET_KEEPALIVE, or
+ * an asynchronous
+ * error notification.
+ *
+ * This is also sent by KeepaliveTracker to the app's
+ * ConnectivityManager.PacketKeepalive to
+ * so that the app's PacketKeepaliveCallback methods can be called.
+ *
+ * arg1 = slot number of the keepalive
+ * arg2 = error code
+ */
+ public static final int EVENT_PACKET_KEEPALIVE = BASE + 13;
+
+ /**
+ * Sent by ConnectivityService to inform this network transport of signal
+ * strength thresholds
+ * that when crossed should trigger a system wakeup and a
+ * NetworkCapabilities update.
+ *
+ * obj = int[] describing signal strength thresholds.
+ */
+ public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14;
+
+ /**
+ * Sent by ConnectivityService to the NeworkAgent to inform the agent to
+ * avoid
+ * automatically reconnecting to this network (e.g. via autojoin). Happens
+ * when user selects "No" option on the "Stay connected?" dialog box.
+ */
+ public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
+
+ public RepWifiNetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
+ NetworkCapabilitiesProxy nc, LinkPropertiesProxy lp, int score) {
+
+ super(looper);
+
+ LOG_TAG = logTag;
+ mContext = context;
+ if (ni == null || nc == null || lp == null) {
+ throw new IllegalArgumentException();
+ }
+
+ if (VDBG)
+ log("Registering NetworkAgent");
+
+ ConnectivityManagerProxy cm = new ConnectivityManagerProxy(mContext);
+
+ myMessenger = new Messenger(this);
+ netId = cm.registerNetworkAgent(myMessenger, new NetworkInfoProxy(ni),
+ new LinkPropertiesProxy(lp), new NetworkCapabilitiesProxy(nc), score);
+
+ }
+
+ public boolean isChannellConnected() {
+ return (mAsyncChannel != null);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+
+ switch (msg.what) {
+ case AsyncChannelProxy.CMD_CHANNEL_FULL_CONNECTION: {
+ if (mAsyncChannel != null) {
+ log("Received new connection while already connected!");
+ } else {
+ if (VDBG)
+ log("NetworkAgent fully connected");
+ AsyncChannelProxy ac = new AsyncChannelProxy();
+ ac.connected(null, this, msg.replyTo);
+ ac.replyToMessage(msg, AsyncChannelProxy.CMD_CHANNEL_FULLY_CONNECTED,
+ AsyncChannelProxy.STATUS_SUCCESSFUL);
+ synchronized (mPreConnectedQueue) {
+ mAsyncChannel = ac;
+ for (Message m : mPreConnectedQueue) {
+ ac.sendMessage(m);
+ }
+ mPreConnectedQueue.clear();
+ }
+ }
+ break;
+ }
+ case AsyncChannelProxy.CMD_CHANNEL_DISCONNECT: {
+ if (VDBG)
+ log("CMD_CHANNEL_DISCONNECT");
+ if (mAsyncChannel != null)
+ mAsyncChannel.disconnect();
+ break;
+ }
+ case AsyncChannelProxy.CMD_CHANNEL_DISCONNECTED: {
+ if (DBG)
+ log("NetworkAgent channel lost");
+ // let the client know CS is done with us.
+
+ synchronized (mPreConnectedQueue) {
+ mAsyncChannel = null;
+ }
+ break;
+ }
+ case CMD_SUSPECT_BAD: {
+ log("Unhandled Message " + msg);
+ break;
+ }
+ case CMD_REQUEST_BANDWIDTH_UPDATE: {
+ long currentTimeMs = System.currentTimeMillis();
+ if (VDBG) {
+ log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
+ }
+ if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
+ mPollLceScheduled = false;
+ if (mPollLcePending.getAndSet(true) == false) {
+
+ shouldCallUninimplementedMethod("pollLceData()");
+
+ }
+ } else {
+ // deliver the request at a later time rather than discard it
+ // completely.
+ if (!mPollLceScheduled) {
+ long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS - currentTimeMs + 1;
+ mPollLceScheduled = sendEmptyMessageDelayed(CMD_REQUEST_BANDWIDTH_UPDATE,
+ waitTime);
+ }
+ }
+ break;
+ }
+ case CMD_REPORT_NETWORK_STATUS: {
+ if (VDBG) {
+ log("CMD_REPORT_NETWORK_STATUS("
+ + (msg.arg1 == VALID_NETWORK ? "VALID)" : "INVALID)"));
+ }
+ shouldCallUninimplementedMethod("shounetworkStatus(msg.arg1)");
+ break;
+ }
+ case CMD_SAVE_ACCEPT_UNVALIDATED: {
+ shouldCallUninimplementedMethod("saveAcceptUnvalidated(msg.arg1 != 0)");
+
+ break;
+ }
+ case CMD_START_PACKET_KEEPALIVE: {
+ shouldCallUninimplementedMethod("startPacketKeepalive(msg)");
+ break;
+ }
+ case CMD_STOP_PACKET_KEEPALIVE: {
+ shouldCallUninimplementedMethod("stopPacketKeepalive(msg)");
+
+ break;
+ }
+
+ case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
+ ArrayList<Integer> thresholds = ((Bundle) msg.obj).getIntegerArrayList("thresholds");
+ int[] intThresholds = new int[(thresholds != null) ? thresholds.size() : 0];
+ for (int i = 0; i < intThresholds.length; i++) {
+ intThresholds[i] = thresholds.get(i);
+ }
+ shouldCallUninimplementedMethod("setSignalStrengthThresholds(intThresholds)");
+ break;
+ }
+ case CMD_PREVENT_AUTOMATIC_RECONNECT: {
+ shouldCallUninimplementedMethod("preventAutomaticReconnect()");
+ break;
+ }
+ default: {
+ String rep = "";
+ if (msg.replyTo != null) {
+ rep = msg.replyTo.toString();
+ }
+ log("Received unhandled message: what = " + msg.what + " replyTo: " + rep);
+ }
+ }
+ }
+
+ private void queueOrSendMessage(int what, Object obj) {
+ queueOrSendMessage(what, 0, 0, obj);
+ }
+
+ /*
+ * private void queueOrSendMessage(int what, int arg1, int arg2) {
+ * queueOrSendMessage(what, arg1, arg2, null);
+ * }
+ */
+
+ private void queueOrSendMessage(int what, int arg1, int arg2, Object obj) {
+ if (VDBG)
+ log("Send or queue message; what=" + what);
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.arg1 = arg1;
+ msg.arg2 = arg2;
+ msg.obj = obj;
+ msg.replyTo = this.myMessenger;
+
+ queueOrSendMessage(msg);
+ }
+
+ private void queueOrSendMessage(Message msg) {
+ synchronized (mPreConnectedQueue) {
+ if (mAsyncChannel != null) {
+ if (VDBG)
+ log("Actually sending message " + msg);
+ mAsyncChannel.sendMessage(msg);
+ } else {
+ mPreConnectedQueue.add(msg);
+ }
+ }
+ }
+
+ /**
+ * Called by the bearer code when it has new LinkProperties data.
+ */
+ public void sendLinkProperties(LinkPropertiesProxy linkProperties) {
+ queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED,
+ new LinkPropertiesProxy(linkProperties).inner);
+ }
+
+ /**
+ * Called by the bearer code when it has new NetworkInfo data.
+ */
+ public void sendNetworkInfo(NetworkInfo networkInfo) {
+ queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED,
+ new NetworkInfoProxy(networkInfo).getNetworkInfo());
+ }
+
+ /**
+ * Called by the bearer code when it has new NetworkCapabilities data.
+ */
+ public void sendNetworkCapabilities(NetworkCapabilitiesProxy networkCapabilities) {
+ mPollLcePending.set(false);
+ mLastBwRefreshTime = System.currentTimeMillis();
+ queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, new NetworkCapabilitiesProxy(
+ networkCapabilities).inner);
+ }
+
+ /**
+ * Called by the bearer code when it has a new score for this network.
+ */
+ public void sendNetworkScore(int score) {
+ if (score < 0) {
+ throw new IllegalArgumentException("Score must be >= 0");
+ }
+ queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, Integer.valueOf(score));
+ }
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, "NetworkAgent: " + s);
+ }
+
+ private void shouldCallUninimplementedMethod(String methodName) {
+ String msg = "[WRN] Should be calling " + methodName
+ + " but the method is not implemented by the proxy..";
+ Log.w(LOG_TAG, msg);
+ }
+
+ /*
+ * A proxy for package com.android.internal.util.AsyncChannel;
+ * Mererly replicates constants and functions needed by the NetworkAgent to
+ * communicate with the other side of the Handler
+ */
+ private static class AsyncChannelProxy extends FrameworkProxy {
+
+ // as in com.android.internal.util.Protocol.BASE_SYSTEM_ASYNC_CHANNEL;
+ private static final int BASE = 0x00011000;
+
+ /** Successful status always 0, !0 is an unsuccessful status */
+ public static final int STATUS_SUCCESSFUL = 0;
+
+ /**
+ * Command typically sent when after receiving the
+ * CMD_CHANNEL_HALF_CONNECTED.
+ * This is used to initiate a long term connection with the destination
+ * and
+ * typically the destination will reply with
+ * CMD_CHANNEL_FULLY_CONNECTED.
+ *
+ * msg.replyTo = srcMessenger.
+ */
+ public static final int CMD_CHANNEL_FULL_CONNECTION = BASE + 1;
+
+ /**
+ * Command typically sent after the destination receives a
+ * CMD_CHANNEL_FULL_CONNECTION.
+ * This signifies the acceptance or rejection of the channel by the
+ * sender.
+ *
+ * msg.arg1 == 0 : Accept connection
+ * : All other values signify the destination rejected the connection
+ * and {@link AsyncChannel#disconnect} would typically be called.
+ */
+ public static final int CMD_CHANNEL_FULLY_CONNECTED = BASE + 2;
+
+ /**
+ * Command sent when one side or the other wishes to disconnect. The
+ * sender
+ * may or may not be able to receive a reply depending upon the protocol
+ * and
+ * the state of the connection. The receiver should call
+ * {@link AsyncChannel#disconnect} to close its side of the channel and
+ * it will receive a CMD_CHANNEL_DISCONNECTED
+ * when the channel is closed.
+ *
+ * msg.replyTo = messenger that is disconnecting
+ */
+ public static final int CMD_CHANNEL_DISCONNECT = BASE + 3;
+
+ /**
+ * Command sent when the channel becomes disconnected. This is sent when
+ * the
+ * channel is forcibly disconnected by the system or as a reply to
+ * CMD_CHANNEL_DISCONNECT.
+ *
+ * msg.arg1 == 0 : STATUS_SUCCESSFUL
+ * 1 : STATUS_BINDING_UNSUCCESSFUL
+ * 2 : STATUS_SEND_UNSUCCESSFUL
+ * : All other values signify failure and the channel state is
+ * indeterminate
+ * msg.obj == the AsyncChannel
+ * msg.replyTo = messenger disconnecting or null if it was never
+ * connected.
+ */
+ public static final int CMD_CHANNEL_DISCONNECTED = BASE + 4;
+
+ /*
+ * Following is a block of unused system constants, kept here for future
+ * reference
+ *//**
+ * Command sent when the channel is half connected. Half connected
+ * means that the channel can be used to send commends to the
+ * destination
+ * but the destination is unaware that the channel exists. The first
+ * command sent to the destination is typically
+ * CMD_CHANNEL_FULL_CONNECTION if
+ * it is desired to establish a long term connection, but any command
+ * maybe
+ * sent.
+ *
+ * msg.arg1 == 0 : STATUS_SUCCESSFUL
+ * 1 : STATUS_BINDING_UNSUCCESSFUL
+ * msg.obj == the AsyncChannel
+ * msg.replyTo == dstMessenger if successful
+ */
+ /*
+ * public static final int CMD_CHANNEL_HALF_CONNECTED = BASE + 0;
+ *
+ * private static final int CMD_TO_STRING_COUNT =
+ * CMD_CHANNEL_DISCONNECTED - BASE + 1;
+ *//** Error attempting to bind on a connect */
+ /*
+ * public static final int STATUS_BINDING_UNSUCCESSFUL = 1;
+ *//** Error attempting to send a message */
+ /*
+ * public static final int STATUS_SEND_UNSUCCESSFUL = 2;
+ *//** CMD_FULLY_CONNECTED refused because a connection already exists */
+ /*
+ * public static final int
+ * STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED = 3;
+ *//** Error indicating abnormal termination of destination messenger */
+ /*
+ * public static final int STATUS_REMOTE_DISCONNECTION = 4;
+ */
+
+ public AsyncChannelProxy() {
+ createInnerObject(null);
+ }
+
+ @Override
+ protected String getInnerClassName() {
+ return "com.android.internal.util.AsyncChannel";
+ }
+
+ public void connected(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
+ invokeMethod("connected", getTypesArray(Context.class, Handler.class, Messenger.class),
+ srcContext, srcHandler, dstMessenger);
+ }
+
+ public void disconnect() {
+ invokeMethod("disconnect", null);
+ }
+
+ public void sendMessage(Message msg) {
+ invokeMethod("sendMessage", Message.class, msg);
+ }
+
+ public void replyToMessage(Message srcMsg, int what, int arg1) {
+ invokeMethod("replyToMessage", getTypesArray(Message.class, int.class, int.class),
+ srcMsg, what, arg1);
+ }
+
+ }
+
+}
diff --git a/app/src/fil/libre/repwifiapp/fwproxies/RouteInfoProxy.java b/app/src/fil/libre/repwifiapp/fwproxies/RouteInfoProxy.java
new file mode 100644
index 0000000..ad2e9f6
--- /dev/null
+++ b/app/src/fil/libre/repwifiapp/fwproxies/RouteInfoProxy.java
@@ -0,0 +1,59 @@
+//
+// Copyright 2017, 2018 Filippo "Fil" Bergamo <fil.bergamo@riseup.net>
+//
+// 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 <http://www.gnu.org/licenses/>.
+//
+// ********************************************************************
+//
+// This file is derivative work, inspired by the original class definition:
+// "android.net.RouteInfo.java" as found in version 6.0 of the Android Operating System.
+// Following is the original copyright notice:
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package fil.libre.repwifiapp.fwproxies;
+
+import java.net.InetAddress;
+
+public class RouteInfoProxy extends FrameworkProxy{
+
+ @Override
+ protected String getInnerClassName() {
+ return "android.net.RouteInfo";
+ }
+
+ public RouteInfoProxy(InetAddress gateway, String ifaceName) {
+ Class<?>[] sig = new Class<?>[]{getClassFromName("android.net.IpPrefix"),
+ InetAddress.class, String.class};
+ createInnerObject(sig, null, gateway, ifaceName);
+ }
+
+
+
+}