Skip to content

Commit d9bc296

Browse files
committed
Add support for Android 10.
1 parent c009e69 commit d9bc296

File tree

8 files changed

+92
-49
lines changed

8 files changed

+92
-49
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ in Computer Science at the University of Oxford, under the supervision
3232
of Professor Max van Kleek.
3333

3434
## Installation / Download
35-
36-
*Supported Android versions: 5.1 to 9. Android 10 is not supported.*
37-
3835
The app can be [downloaded here](https://github.com/OxfordHCC/tracker-control-android/releases).
3936

4037
Alternatively, there exists a [repository for F-Droid](https://apt.izzysoft.de/fdroid/index/apk/net.kollnig.missioncontrol).
@@ -106,6 +103,8 @@ The original data can be retrieved [here](https://osf.io/4nu9e/).
106103

107104
The app uses icons made by [bqlqn](https://www.flaticon.com/authors/bqlqn) from [www.flaticon.com](https://www.flaticon.com/).
108105

106+
For the GDPR requests, the templates from the website [My Data Done Right](https://www.mydatadoneright.eu/) by the NGO "Bits of Freedom" were adopted.
107+
109108
## License
110109
This project is licensed under
111110
[GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).

app/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,14 @@ repositories {
8787
dependencies {
8888
implementation fileTree(include: ['*.jar'], dir: 'libs')
8989
implementation(name: 'antmonitorlib', ext: 'aar')
90-
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
9190

9291
implementation 'androidx.appcompat:appcompat:1.1.0'
9392
implementation 'com.google.android.material:material:1.0.0'
9493
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
9594
implementation 'androidx.cardview:cardview:1.0.0'
9695
implementation 'androidx.recyclerview:recyclerview:1.0.0'
96+
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
9797
implementation 'androidx.preference:preference:1.1.0'
98-
implementation 'com.google.android.material:material:1.0.0'
9998

10099
implementation 'com.google.guava:guava:28.0-android'
101100
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

app/libs/antmonitorlib.aar

Lines changed: 0 additions & 1 deletion
This file was deleted.

app/libs/antmonitorlib.aar

7.39 MB
Binary file not shown.

app/src/main/java/net/kollnig/missioncontrol/MainActivity.java

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import android.content.Intent;
2323
import android.content.SharedPreferences;
2424
import android.net.Uri;
25-
import android.os.Build;
2625
import android.os.Bundle;
2726
import android.util.Log;
2827
import android.view.Menu;
@@ -110,39 +109,29 @@ protected void onCreate (Bundle savedInstanceState) {
110109
}
111110

112111
// Ask for consent to contact Google and other servers
113-
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
112+
final SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
114113
boolean firstStart = sharedPref.getBoolean(FIRST_START, true);
115114

116-
final SharedPreferences settingsPref = PreferenceManager
117-
.getDefaultSharedPreferences(this);
118-
119-
AlertDialog.Builder builder = new AlertDialog.Builder(this);
120-
if (firstStart && android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
115+
if (firstStart) {
121116
sharedPref.edit().putBoolean(FIRST_START, false).apply();
122117

118+
AlertDialog.Builder builder = new AlertDialog.Builder(this);
123119
builder.setMessage(R.string.confirm_google_info)
124120
.setTitle(R.string.external_servers);
125121
builder.setPositiveButton(R.string.yes, (dialog, id) -> {
126-
settingsPref.edit().putBoolean
122+
sharedPref.edit().putBoolean
127123
(SettingsActivity.KEY_PREF_GOOGLEPLAY_SWITCH, true).apply();
128124
dialog.dismiss();
129125
});
130126
builder.setNegativeButton(R.string.no, (dialog, id) -> {
131127
dialog.dismiss();
132128
});
133-
} else {
134-
builder.setMessage(R.string.android_10_unsupported_explanation)
135-
.setTitle(R.string.android_10_unsupported_title);
136-
builder.setPositiveButton(R.string.ok, (dialog, id) -> {
137-
dialog.dismiss();
138-
});
139-
}
140-
AlertDialog dialog = builder.create();
141-
dialog.setCancelable(false); // avoid back button
142-
dialog.setCanceledOnTouchOutside(false);
143-
dialog.show();
144129

145-
//throw new RuntimeException("Dying on purpose"); // to test crash reporting
130+
AlertDialog dialog = builder.create();
131+
dialog.setCancelable(false); // avoid back button
132+
dialog.setCanceledOnTouchOutside(false);
133+
dialog.show();
134+
}
146135
}
147136

148137
/**

app/src/main/java/net/kollnig/missioncontrol/details/PolicyFragment.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,14 @@ public void run () {
182182
return;
183183
}
184184

185-
String privacyHtml;
185+
boolean fetchError = false;
186+
String privacyHtml = null;
186187
try {
187188
privacyHtml = fetch(policyUrl);
188189
} catch (Exception e) {
190+
fetchError = true;
191+
}
192+
if (fetchError || privacyHtml == null) {
189193
Log.d(TAG, "Fetching of policy from url failed.");
190194
onError(policyUrl);
191195
return;

app/src/main/java/net/kollnig/missioncontrol/vpn/OutConsumer.java

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
package net.kollnig.missioncontrol.vpn;
1818

1919
import android.content.Context;
20+
import android.content.pm.PackageManager;
21+
import android.net.ConnectivityManager;
2022
import android.util.Log;
2123

2224
import net.kollnig.missioncontrol.data.Database;
23-
import net.kollnig.missioncontrol.main.AppBlocklistController;
2425

26+
import java.net.InetSocketAddress;
2527
import java.nio.ByteBuffer;
2628

2729
import edu.uci.calit2.antmonitor.lib.logging.ConnectionValue;
@@ -31,17 +33,25 @@
3133
import edu.uci.calit2.antmonitor.lib.util.PacketDumpInfo;
3234
import edu.uci.calit2.antmonitor.lib.vpn.VpnController;
3335

36+
import static android.os.Process.INVALID_UID;
37+
import static android.system.OsConstants.IPPROTO_TCP;
38+
import static android.system.OsConstants.IPPROTO_UDP;
39+
3440
public class OutConsumer extends PacketConsumer {
3541
private final String TAG = OutConsumer.class.getSimpleName();
3642
private final Context mContext;
37-
private final AppBlocklistController appBlocklist;
38-
private Database database;
43+
private final Database database;
44+
private final PackageManager pm;
45+
46+
ConnectivityManager connectivityManager;
3947

4048
public OutConsumer (Context c, TrafficType trafficType) {
4149
super(c, trafficType, null);
4250
database = Database.getInstance(c);
4351
mContext = c;
44-
appBlocklist = AppBlocklistController.getInstance(c);
52+
53+
connectivityManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
54+
pm = c.getPackageManager();
4555
}
4656

4757
static String getHostname (String remoteIp) {
@@ -55,31 +65,44 @@ static String getHostname (String remoteIp) {
5565
*/
5666
@Override
5767
protected void consumePacket (PacketDumpInfo packetDumpInfo) {
58-
// Identify sending app
59-
ConnectionValue cv = mapPacketToApp(packetDumpInfo);
60-
String appname = cv.getAppName();
61-
if (appname.startsWith(ConnectionValue.MappingErrors.PREFIX)
62-
// || (appBlocklist.systemApps.contains(cv.getAppName()))
63-
)
64-
return;
65-
6668
// Parse IP packet
6769
byte[] packet = packetDumpInfo.getDump();
6870
IpDatagram ipDatagram = new IpDatagram(ByteBuffer.wrap(packet));
6971

70-
// Restrict logging to TCP
71-
/*short protocol = ipDatagram.getProtocol();
72-
if (protocol != IpDatagram.TCP) return;*/
72+
// Identify sending app
73+
String appname;
74+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
75+
// Only UDP and TCP are supported
76+
short protocol = ipDatagram.getProtocol();
77+
if (protocol != IpDatagram.UDP && protocol != IpDatagram.TCP)
78+
return;
79+
80+
int lookupProtocol = (protocol == IpDatagram.TCP) ? IPPROTO_TCP : IPPROTO_UDP;
81+
82+
InetSocketAddress local = new InetSocketAddress
83+
(ipDatagram.getSourceIP(), IpDatagram.readSourcePort(packet));
84+
InetSocketAddress remote = new InetSocketAddress
85+
(ipDatagram.getDestinationIP(), IpDatagram.readDestinationPort(packet));
86+
87+
int uid = connectivityManager.getConnectionOwnerUid(lookupProtocol, local, remote);
88+
if (uid == INVALID_UID)
89+
return;
90+
91+
appname = getAppName(uid);
92+
} else {
93+
ConnectionValue cv = mapPacketToApp(packetDumpInfo);
94+
appname = cv.getAppName();
95+
if (appname.startsWith
96+
(ConnectionValue.MappingErrors.PREFIX)) {
97+
return;
98+
}
99+
}
73100

74101
// Log packet in database
75102
String remoteIp = ipDatagram.getDestinationIP().getHostAddress();
76103
String hostname = getHostname(remoteIp);
77104
if (hostname == null) hostname = remoteIp;
78105
database.logPacketAsyncTask(mContext, appname, remoteIp, hostname);
79-
80-
if (remoteIp.equals("8.8.8.8")) {
81-
Log.d(TAG, remoteIp);
82-
}
83106
}
84107

85108
/**
@@ -90,4 +113,36 @@ protected void consumePacket (PacketDumpInfo packetDumpInfo) {
90113
protected void onStop () {
91114

92115
}
116+
117+
/**
118+
* Retrieves the name of the app based on the given uid
119+
*
120+
* @param uid - of the app
121+
* @return the name of the package of the app with the given uid, or "Unknown" if
122+
* no name could be found for the uid.
123+
*/
124+
public String getAppName (int uid) {
125+
/* IMPORTANT NOTE:
126+
* From https://source.android.com/devices/tech/security/ : "The Android
127+
* system assigns a unique user ID (UID) to each Android application and
128+
* runs it as that user in a separate process"
129+
*
130+
* However, there is an exception: "A closer relationship with a shared
131+
* Application Sandbox is allowed via the shared UID feature where two
132+
* or more applications signed with same developer key can declare a
133+
* shared UID in their manifest."
134+
*/
135+
136+
// See if this is root
137+
if (uid == 0)
138+
return "System";
139+
140+
// If we can't find a running app, just get a list of packages that map to the uid
141+
String[] packages = pm.getPackagesForUid(uid);
142+
if (packages != null && packages.length > 0)
143+
return packages[0];
144+
145+
Log.w(TAG, "Process with uid " + uid + " does not appear to be running!");
146+
return "Unknown";
147+
}
93148
}

app/src/main/res/values/strings.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,4 @@ Sincerely,]]></string>
155155
<string name="menu_settings">Settings</string>
156156

157157
<string name="instructions_monitoring">"Interact with your apps to detect some trackers."</string>
158-
159-
<string name="android_10_unsupported_title">Android 10 unsupported</string>
160-
<string name="android_10_unsupported_explanation">Support will be added soon. Monitoring or blocking of trackers does not work in this version.</string>
161158
</resources>

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ buildscript {
2525
google()
2626
}
2727
dependencies {
28-
classpath 'com.android.tools.build:gradle:3.4.2'
28+
classpath 'com.android.tools.build:gradle:3.5.2'
2929

3030
// NOTE: Do not place your application dependencies here; they belong
3131
// in the individual module build.gradle files

0 commit comments

Comments
 (0)