[Replicant] [PATCH] fix repwifi connection not reported to userspace apps. fix reverse-tether connection not reported to userspace apps.
Fil
fil.bergamo at riseup.net
Mon May 22 21:47:41 UTC 2017
Dear Replicant fellows,
As reported on the tracker I've finished my work on issue #1792.
Here-below is my very first patch to replicant (hurray!!!).
It is my very first patch to anything, to say the truth, so I just hope everything was done properly and I hope it works as expected.
Please pardon me if I messed up with anything while packing up the patch.
Here it is:
---
api/current.txt | 2 +
api/system-current.txt | 2 +
core/java/android/net/NetworkInfo.java | 268 +++++++++++++++++++++
.../com/android/server/ConnectivityService.java | 11 +
4 files changed, 283 insertions(+)
diff --git a/api/current.txt b/api/current.txt
index c45cc3dbbf4..2a3ab95c4bf 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18372,9 +18372,11 @@ package android.net {
method public android.net.NetworkInfo.DetailedState getDetailedState();
method public java.lang.String getExtraInfo();
method public java.lang.String getReason();
+ method public static android.net.NetworkInfo getRepWifiNetworkInfo();
method public android.net.NetworkInfo.State getState();
method public int getSubtype();
method public java.lang.String getSubtypeName();
+ method public static android.net.NetworkInfo getTetherNetworkInfo();
method public int getType();
method public java.lang.String getTypeName();
method public boolean isAvailable();
diff --git a/api/system-current.txt b/api/system-current.txt
index 1e7b94e883e..12f87e9d2a6 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -19885,9 +19885,11 @@ package android.net {
method public android.net.NetworkInfo.DetailedState getDetailedState();
method public java.lang.String getExtraInfo();
method public java.lang.String getReason();
+ method public static android.net.NetworkInfo getRepWifiNetworkInfo();
method public android.net.NetworkInfo.State getState();
method public int getSubtype();
method public java.lang.String getSubtypeName();
+ method public static android.net.NetworkInfo getTetherNetworkInfo();
method public int getType();
method public java.lang.String getTypeName();
method public boolean isAvailable();
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index af7a4658808..8f61c83d989 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -21,6 +21,9 @@ import android.os.Parcel;
import com.android.internal.annotations.VisibleForTesting;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.EnumMap;
/**
@@ -471,4 +474,269 @@ public class NetworkInfo implements Parcelable {
return new NetworkInfo[size];
}
};
+
+ // ****** Extension methods for RepWifi **********
+ // Introduced by Fil Bergamo, 2017-05-16.
+ //
+ public static NetworkInfo getRepWifiNetworkInfo(){
+ return RepWifiConnection.getNetworkInfo(RepWifiConnection.INTERFACE_NAME_WIFI);
+ }
+
+ public static NetworkInfo getTetherNetworkInfo(){
+ return RepWifiConnection.getNetworkInfo(RepWifiConnection.INTERFACE_NAME_TETHER);
+ }
+
+ static class RepWifiConnection{
+
+ static final String INTERFACE_NAME_WIFI = "wlan0";
+ static final String INTERFACE_NAME_TETHER = "rndis0";
+
+ static class ShellCommand {
+
+ protected String _cmdOut = "";
+ protected String _cmdTxt = "";
+
+ public ShellCommand(String commandText) {
+ this._cmdTxt = commandText;
+ }
+
+ public int execute() throws Exception {
+
+ if (this._cmdTxt == null) {
+ return -9;
+ }
+
+ java.lang.Process cmd = Runtime.getRuntime().exec(this._cmdTxt);
+
+ InputStream os = cmd.getInputStream();
+ InputStream es = cmd.getErrorStream();
+
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(getStringFromStream(es));
+ sb.append(getStringFromStream(os));
+
+ int res = cmd.waitFor();
+
+ // re-read the output, in case it was empty when first tried
+ sb.append(getStringFromStream(es));
+ sb.append(getStringFromStream(os));
+
+ this._cmdOut = sb.toString();
+
+ return res;
+
+ }
+
+ protected String getStringFromStream(InputStream s) throws IOException {
+
+ StringBuilder sb = new StringBuilder();
+ while ((s.available() > 0)) {
+ int b = s.read();
+ if (b >= 0) {
+ sb.append((char) b);
+ } else {
+ break;
+ }
+ }
+
+ return sb.toString();
+
+ }
+
+ public String getOutput() {
+ return this._cmdOut;
+ }
+
+ }
+
+ public static NetworkInfo getNetworkInfo(String interfaceName){
+
+ NetworkInfo netInfo;
+ if (interfaceName.equals(INTERFACE_NAME_WIFI)){
+ netInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", "");
+
+ }else if (interfaceName.equals(INTERFACE_NAME_TETHER)){
+ netInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0,"ETHERNET", "");
+
+ }else{
+ return null;
+ }
+
+ netInfo.mState = getState(interfaceName);
+ netInfo.mDetailedState = getDetailedState(interfaceName);
+ netInfo.mIsAvailable = isAvailable(interfaceName);
+ return netInfo;
+
+ }
+
+ public static boolean isAvailable(String interfaceName){
+
+ String[] ifaces = getAvailableInterfaces();
+ if (ifaces == null){
+ return false;
+ }
+
+ if (ifaces.length == 0){
+ return false;
+ }
+
+ for (String i : ifaces){
+ if (i.equals(interfaceName)){
+ return true;
+ }
+ }
+
+ return false;
+
+ }
+
+ public static State getState(String interfaceName){
+
+ if (interfaceName.equals(INTERFACE_NAME_WIFI) && (! isWpaSupplicantRunning())){
+ return State.DISCONNECTED;
+ }
+
+ String gw = getGateway(interfaceName);
+ if (gw == null){
+ return State.DISCONNECTED;
+ }
+ else{
+ //assuming the following:
+ //if there's a gateway set for the interface,
+ //then there's a route for the interface,
+ //then RepWifi or reverse-tether must have established that route,
+ //then RepWifi or reverse-tether is connected.
+ return State.CONNECTED;
+ }
+
+ }
+
+ public static DetailedState getDetailedState(String interfaceName){
+
+ State currentState = getState(interfaceName);
+ if (currentState == State.CONNECTED){
+ return DetailedState.CONNECTED;
+ }
+ else{
+ return DetailedState.DISCONNECTED;
+ }
+
+ }
+
+ private static boolean isWpaSupplicantRunning(){
+
+ boolean retval = false;
+
+ try {
+
+ ShellCommand su = new ShellCommand("pidof wpa_supplicant");
+ if (su.execute() == 0){
+
+ if (su.getOutput().trim().equals("")){
+ retval = false;
+ }else{
+ retval = true;
+ }
+
+ }else {
+ retval = false;
+ }
+
+
+ } catch (Exception e) {
+ retval = false;
+ }
+
+ return retval;
+
+ }
+
+ protected static String getGateway(String interfaceName){
+
+ try {
+
+ //doesn't need root (tested)
+ ShellCommand cmd = new ShellCommand("ip route show dev " + interfaceName);
+ if (cmd.execute() != 0){
+ return null;
+ }
+
+ //read command output
+ String out = cmd.getOutput();
+ if (out == null){
+ return null;
+ }
+
+ String[] lines = out.split("\n");
+
+ for (String l : lines){
+
+ if (l.contains("default via")){
+
+ String[] f = l.split(" ");
+ if (f.length > 2){
+
+ //found route's address:
+ return f[2];
+
+ }
+ }
+ }
+
+ return null;
+
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+
+ protected static String[] getAvailableInterfaces(){
+
+ try {
+
+ // No need for root for "ip link"
+ // tested 2017-03-24 - Fil
+ ShellCommand cmd = new ShellCommand("ip link");
+ if (cmd.execute() == 0){
+
+ String out = cmd.getOutput();
+ if (out == null || out.contains("\n") == false){
+ return null;
+ }
+
+ ArrayList<String> list = new ArrayList<String>();
+
+ String[] lines = out.split("\n");
+ for (String l : lines){
+
+ String[] fields = l.split(":");
+ if (fields.length != 3){
+ continue;
+ }
+
+ String interfName = fields[1].trim();
+ list.add(interfName);
+
+ }
+
+ String[] retArr = new String[list.size()];
+ retArr = list.toArray(retArr);
+
+ return retArr;
+
+ }
+ else{
+ return null;
+ }
+
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+
+ }
+ //***** End of Extension methods for RepWifi***************
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1489fd8713a..bf7165682fe 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1017,6 +1017,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int uid = Binder.getCallingUid();
NetworkState state = getUnfilteredActiveNetworkState(uid);
NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+
+ //***** Begin Extension for RepWifi *******
+ //introduced by Fil Bergamo 2017-05-16
+ if (ni == null){
+ ni = NetworkInfo.getRepWifiNetworkInfo();
+ }
+ if (ni == null || ni.isAvailable() == false || ni.getState() != NetworkInfo.State.CONNECTED){
+ ni = NetworkInfo.getTetherNetworkInfo();
+ }
+ //***** End of Extension for RepWifi. *****
+
maybeLogBlockedNetworkInfo(ni, uid);
return ni;
}
--
2.11.0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/replicant/attachments/20170522/59b8db69/attachment.asc>
More information about the Replicant
mailing list