Android O compatibility

This commit is contained in:
M66B 2017-07-31 10:53:37 +02:00
parent 8cd746e0d4
commit 9aef8e8ef0
7 changed files with 231 additions and 182 deletions

View File

@ -50,6 +50,13 @@
<sourceFolder url="file://$MODULE_DIR$/src/allDebug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/allDebug/renderscript" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/allDebug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/all/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/all/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/assets" type="java-test-resource" />
@ -58,13 +65,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/all/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/all/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/all/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/all/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/all/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/all/assets" type="java-resource" />
@ -72,14 +72,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/all/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/all/renderscript" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/all/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testAll/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testAll/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testAll/assets" type="java-test-resource" />
@ -88,6 +80,14 @@
<sourceFolder url="file://$MODULE_DIR$/src/testAll/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testAll/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testAll/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@ -143,36 +143,35 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="jdk" jdkName="Android API 26 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="play-services-basement-11.0.2" level="project" />
<orderEntry type="library" exported="" name="play-services-ads-lite-11.0.2" level="project" />
<orderEntry type="library" exported="" name="support-core-ui-26.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-ads-lite-11.0.4" level="project" />
<orderEntry type="library" exported="" name="picasso-2.5.2" level="project" />
<orderEntry type="library" exported="" name="firebase-ads-11.0.2" level="project" />
<orderEntry type="library" exported="" name="firebase-iid-11.0.2" level="project" />
<orderEntry type="library" exported="" name="support-core-ui-25.4.0" level="project" />
<orderEntry type="library" exported="" name="play-services-ads-11.0.2" level="project" />
<orderEntry type="library" exported="" name="play-services-gass-11.0.2" level="project" />
<orderEntry type="library" exported="" name="firebase-core-11.0.2" level="project" />
<orderEntry type="library" exported="" name="support-core-utils-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-fragment-25.4.0" level="project" />
<orderEntry type="library" exported="" name="play-services-base-11.0.2" level="project" />
<orderEntry type="library" exported="" name="play-services-clearcut-11.0.2" level="project" />
<orderEntry type="library" exported="" name="play-services-safetynet-11.0.2" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-11.0.2" level="project" />
<orderEntry type="library" exported="" name="support-v4-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-media-compat-25.4.0" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-25.4.0" level="project" />
<orderEntry type="library" exported="" name="firebase-common-11.0.2" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-impl-11.0.2" level="project" />
<orderEntry type="library" exported="" name="play-services-tasks-11.0.2" level="project" />
<orderEntry type="library" exported="" name="support-annotations-25.4.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-compat-25.4.0" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-25.4.0" level="project" />
<orderEntry type="library" exported="" name="support-media-compat-26.0.0" level="project" />
<orderEntry type="library" exported="" name="firebase-core-11.0.4" level="project" />
<orderEntry type="library" exported="" name="firebase-ads-11.0.4" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-26.0.0" level="project" />
<orderEntry type="library" exported="" name="firebase-iid-11.0.4" level="project" />
<orderEntry type="library" exported="" name="support-core-utils-26.0.0" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-26.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-ads-11.0.4" level="project" />
<orderEntry type="library" exported="" name="play-services-safetynet-11.0.4" level="project" />
<orderEntry type="library" exported="" name="play-services-basement-11.0.4" level="project" />
<orderEntry type="library" exported="" name="play-services-base-11.0.4" level="project" />
<orderEntry type="library" exported="" name="play-services-gass-11.0.4" level="project" />
<orderEntry type="library" exported="" name="support-fragment-26.0.0" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-26.0.0" level="project" />
<orderEntry type="library" exported="" name="support-compat-26.0.0" level="project" />
<orderEntry type="library" exported="" name="play-services-clearcut-11.0.4" level="project" />
<orderEntry type="library" exported="" name="support-v4-26.0.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-26.0.0" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-26.0.0" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-11.0.4" level="project" />
<orderEntry type="library" exported="" name="firebase-analytics-impl-11.0.4" level="project" />
<orderEntry type="library" exported="" name="play-services-tasks-11.0.4" level="project" />
<orderEntry type="library" exported="" name="firebase-common-11.0.4" level="project" />
</component>
</module>

View File

@ -2,7 +2,7 @@ apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 25
compileSdkVersion = 26
buildToolsVersion = "26.0.1"
defaultConfig {
@ -57,14 +57,14 @@ model {
create("all") {
versionName = "2.114"
minSdkVersion.apiLevel = 14
targetSdkVersion.apiLevel = 25
targetSdkVersion.apiLevel = 26
versionCode = 2017072501
archivesBaseName = "NetGuard-v$versionName"
}
create("lollipop-and-later") {
versionName = "2.114"
minSdkVersion.apiLevel = 20
targetSdkVersion.apiLevel = 25
targetSdkVersion.apiLevel = 26
versionCode = 2017072511
archivesBaseName = "NetGuard-v$versionName"
}
@ -72,7 +72,7 @@ model {
versionName = "2.114"
minSdkVersion.apiLevel = 14
maxSdkVersion = 19
targetSdkVersion.apiLevel = 25
targetSdkVersion.apiLevel = 26
versionCode = 2017072521
archivesBaseName = "NetGuard-v$versionName"
}
@ -82,9 +82,8 @@ model {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.+'
compile 'com.android.support:support-annotations:25.+'
compile 'com.android.support:recyclerview-v7:25.+'
compile 'com.android.support:appcompat-v7:26.0.+'
compile 'com.android.support:recyclerview-v7:26.0.+'
compile 'com.squareup.picasso:picasso:2.5.+'
compile 'com.google.firebase:firebase-core:11.0.+'
compile 'com.google.firebase:firebase-ads:11.0.+'

View File

@ -20,6 +20,10 @@ package eu.faircode.netguard;
*/
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.media.AudioAttributes;
import android.util.Log;
public class ApplicationEx extends Application {
@ -32,6 +36,18 @@ public class ApplicationEx extends Application {
super.onCreate();
Log.i(TAG, "Create version=" + Util.getSelfVersionName(this) + "/" + Util.getSelfVersionCode(this));
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel foreground = new NotificationChannel("foreground", getString(R.string.app_name), NotificationManager.IMPORTANCE_MIN);
foreground.setSound(null, new AudioAttributes.Builder().build());
nm.createNotificationChannel(foreground);
NotificationChannel notify = new NotificationChannel("notify", getString(R.string.app_name), NotificationManager.IMPORTANCE_DEFAULT);
notify.setSound(null, new AudioAttributes.Builder().build());
nm.createNotificationChannel(notify);
}
mPrevHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override

View File

@ -20,9 +20,12 @@ package eu.faircode.netguard;
*/
import android.app.IntentService;
import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import java.io.File;
@ -48,76 +51,92 @@ public class ServiceExternal extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "Received " + intent);
Util.logExtras(intent);
try {
startForeground(ServiceSinkhole.NOTIFY_EXTERNAL, getForegroundNotification(this));
if (ACTION_DOWNLOAD_HOSTS_FILE.equals(intent.getAction())) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Log.i(TAG, "Received " + intent);
Util.logExtras(intent);
String hosts_url = prefs.getString("hosts_url", null);
File tmp = new File(getFilesDir(), "hosts.tmp");
File hosts = new File(getFilesDir(), "hosts.txt");
if (ACTION_DOWNLOAD_HOSTS_FILE.equals(intent.getAction())) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
InputStream in = null;
OutputStream out = null;
URLConnection connection = null;
try {
URL url = new URL(hosts_url);
connection = url.openConnection();
connection.connect();
String hosts_url = prefs.getString("hosts_url", null);
File tmp = new File(getFilesDir(), "hosts.tmp");
File hosts = new File(getFilesDir(), "hosts.txt");
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK)
throw new IOException(httpConnection.getResponseCode() + " " + httpConnection.getResponseMessage());
}
int contentLength = connection.getContentLength();
Log.i(TAG, "Content length=" + contentLength);
in = connection.getInputStream();
out = new FileOutputStream(tmp);
long size = 0;
byte buffer[] = new byte[4096];
int bytes;
while ((bytes = in.read(buffer)) != -1) {
out.write(buffer, 0, bytes);
size += bytes;
}
Log.i(TAG, "Downloaded size=" + size);
if (hosts.exists())
hosts.delete();
tmp.renameTo(hosts);
String last = SimpleDateFormat.getDateTimeInstance().format(new Date().getTime());
prefs.edit().putString("hosts_last_download", last).apply();
ServiceSinkhole.reload("hosts file download", this, false);
} catch (Throwable ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
if (tmp.exists())
tmp.delete();
} finally {
InputStream in = null;
OutputStream out = null;
URLConnection connection = null;
try {
if (out != null)
out.close();
} catch (IOException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
try {
if (in != null)
in.close();
} catch (IOException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
URL url = new URL(hosts_url);
connection = url.openConnection();
connection.connect();
if (connection instanceof HttpURLConnection)
((HttpURLConnection) connection).disconnect();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK)
throw new IOException(httpConnection.getResponseCode() + " " + httpConnection.getResponseMessage());
}
int contentLength = connection.getContentLength();
Log.i(TAG, "Content length=" + contentLength);
in = connection.getInputStream();
out = new FileOutputStream(tmp);
long size = 0;
byte buffer[] = new byte[4096];
int bytes;
while ((bytes = in.read(buffer)) != -1) {
out.write(buffer, 0, bytes);
size += bytes;
}
Log.i(TAG, "Downloaded size=" + size);
if (hosts.exists())
hosts.delete();
tmp.renameTo(hosts);
String last = SimpleDateFormat.getDateTimeInstance().format(new Date().getTime());
prefs.edit().putString("hosts_last_download", last).apply();
ServiceSinkhole.reload("hosts file download", this, false);
} catch (Throwable ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
if (tmp.exists())
tmp.delete();
} finally {
try {
if (out != null)
out.close();
} catch (IOException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
try {
if (in != null)
in.close();
} catch (IOException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
if (connection instanceof HttpURLConnection)
((HttpURLConnection) connection).disconnect();
}
}
} finally {
stopForeground(true);
}
}
private static Notification getForegroundNotification(Context context) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "foreground");
builder.setSmallIcon(R.drawable.ic_hourglass_empty_white_24dp);
builder.setPriority(NotificationCompat.PRIORITY_MIN);
builder.setCategory(NotificationCompat.CATEGORY_STATUS);
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
builder.setContentTitle(context.getString(R.string.app_name));
return builder.build();
}
}

View File

@ -156,6 +156,7 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
private static final int NOTIFY_ERROR = 5;
private static final int NOTIFY_TRAFFIC = 6;
private static final int NOTIFY_UPDATE = 7;
public static final int NOTIFY_EXTERNAL = 8;
public static final String EXTRA_COMMAND = "Command";
private static final String EXTRA_REASON = "Reason";
@ -365,7 +366,11 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
if (cmd == Command.start || cmd == Command.reload) {
Intent watchdogIntent = new Intent(ServiceSinkhole.this, ServiceSinkhole.class);
watchdogIntent.setAction(ACTION_WATCHDOG);
PendingIntent pi = PendingIntent.getService(ServiceSinkhole.this, 1, watchdogIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pi;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
pi = PendingIntent.getForegroundService(ServiceSinkhole.this, 1, watchdogIntent, PendingIntent.FLAG_UPDATE_CURRENT);
else
pi = PendingIntent.getService(ServiceSinkhole.this, 1, watchdogIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
@ -994,8 +999,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(ServiceSinkhole.this)
.setWhen(when)
NotificationCompat.Builder builder = new NotificationCompat.Builder(ServiceSinkhole.this, "notify");
builder.setWhen(when)
.setSmallIcon(R.drawable.ic_equalizer_white_24dp)
.setContent(remoteViews)
.setContentIntent(pi)
@ -1003,10 +1008,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
.setOngoing(true)
.setAutoCancel(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_PUBLIC);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
if (state == State.none || state == State.waiting) {
if (state != State.none) {
@ -2041,8 +2045,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_security_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_security_white_24dp)
.setContentIntent(pi)
.setColor(tv.data)
.setAutoCancel(true);
@ -2055,8 +2059,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
.setContentText(getString(R.string.msg_installed, name));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET);
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
// Get defaults
SharedPreferences prefs_wifi = getSharedPreferences("wifi", Context.MODE_PRIVATE);
@ -2243,7 +2247,11 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
// Setup house holding
Intent alarmIntent = new Intent(this, ServiceSinkhole.class);
alarmIntent.setAction(ACTION_HOUSE_HOLDING);
PendingIntent pi = PendingIntent.getService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pi;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
pi = PendingIntent.getForegroundService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
else
pi = PendingIntent.getService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC, SystemClock.elapsedRealtime() + 60 * 1000, AlarmManager.INTERVAL_HALF_DAY, pi);
@ -2425,8 +2433,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(isLockedDown(last_metered) ? R.drawable.ic_lock_outline_white_24dp : R.drawable.ic_security_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "foreground");
builder.setSmallIcon(isLockedDown(last_metered) ? R.drawable.ic_lock_outline_white_24dp : R.drawable.ic_security_white_24dp)
.setContentIntent(pi)
.setColor(tv.data)
.setOngoing(true)
@ -2438,11 +2446,10 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
builder.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_started));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(Notification.PRIORITY_MIN);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.setPriority(NotificationCompat.PRIORITY_MIN);
if (allowed > 0 || blocked > 0 || hosts > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@ -2477,8 +2484,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_security_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "foreground");
builder.setSmallIcon(R.drawable.ic_security_white_24dp)
.setContentIntent(pi)
.setColor(tv.data)
.setOngoing(true)
@ -2490,11 +2497,10 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
builder.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_waiting));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET)
.setPriority(Notification.PRIORITY_MIN);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.setPriority(NotificationCompat.PRIORITY_MIN);
return builder.build();
}
@ -2505,8 +2511,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_error_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_revoked))
.setContentIntent(pi)
@ -2514,10 +2520,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
.setOngoing(false)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
notification.bigText(getString(R.string.msg_revoked));
@ -2532,8 +2537,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_error_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_autostart))
.setContentIntent(pi)
@ -2541,10 +2546,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
.setOngoing(false)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
notification.bigText(getString(R.string.msg_autostart));
@ -2558,8 +2562,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_error_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_error, message))
.setContentIntent(pi)
@ -2567,10 +2571,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
.setOngoing(false)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
notification.bigText(getString(R.string.msg_error, message));
@ -2592,8 +2595,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
int colorOff = tv.data;
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
.setGroup("AccessAttempt")
.setContentIntent(pi)
.setColor(colorOff)
@ -2607,10 +2610,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
builder.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_access, name));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
DateFormat df = new SimpleDateFormat("dd HH:mm");
@ -2662,8 +2664,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
TypedValue tv = new TypedValue();
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_security_white_24dp)
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_security_white_24dp)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.msg_update))
.setContentIntent(pi)
@ -2671,10 +2673,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
.setOngoing(false)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setCategory(Notification.CATEGORY_STATUS)
.setVisibility(Notification.VISIBILITY_SECRET);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
notification.bigText(getString(R.string.msg_update));
@ -2816,14 +2817,20 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
Intent intent = new Intent(context, ServiceSinkhole.class);
intent.putExtra(EXTRA_COMMAND, Command.run);
intent.putExtra(EXTRA_REASON, reason);
context.startService(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(intent);
else
context.startService(intent);
}
public static void start(String reason, Context context) {
Intent intent = new Intent(context, ServiceSinkhole.class);
intent.putExtra(EXTRA_COMMAND, Command.start);
intent.putExtra(EXTRA_REASON, reason);
context.startService(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(intent);
else
context.startService(intent);
}
public static void reload(String reason, Context context, boolean interactive) {
@ -2833,7 +2840,10 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
intent.putExtra(EXTRA_COMMAND, Command.reload);
intent.putExtra(EXTRA_REASON, reason);
intent.putExtra(EXTRA_INTERACTIVE, interactive);
context.startService(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(intent);
else
context.startService(intent);
}
}
@ -2842,13 +2852,19 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
intent.putExtra(EXTRA_COMMAND, Command.stop);
intent.putExtra(EXTRA_REASON, reason);
intent.putExtra(EXTRA_TEMPORARY, vpnonly);
context.startService(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(intent);
else
context.startService(intent);
}
public static void reloadStats(String reason, Context context) {
Intent intent = new Intent(context, ServiceSinkhole.class);
intent.putExtra(EXTRA_COMMAND, Command.stats);
intent.putExtra(EXTRA_REASON, reason);
context.startService(intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
context.startForegroundService(intent);
else
context.startService(intent);
}
}

View File

@ -15,7 +15,7 @@
android:id="@+id/tvTx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:typeface="monospace" />
<TextView
@ -25,7 +25,7 @@
android:layout_marginStart="4dp"
android:alpha="0.5"
android:text="▲"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:textColor="@color/colorSend" />
<TextView
@ -34,7 +34,7 @@
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:typeface="monospace" />
<TextView
@ -44,7 +44,7 @@
android:layout_marginStart="4dp"
android:alpha="0.5"
android:text="▼"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:textColor="@color/colorReceive" />
</LinearLayout>
@ -55,7 +55,7 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:textSize="10sp" />
<TextView
@ -66,7 +66,7 @@
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:singleLine="false"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:textSize="10sp" />
<TextView
@ -76,7 +76,7 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:textSize="10sp" />
<ImageView
@ -96,7 +96,7 @@
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:paddingTop="10sp"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
android:textColor="@color/colorGrayed"
android:textSize="10sp"
android:typeface="monospace" />

View File

@ -7,7 +7,7 @@ buildscript {
dependencies {
// http://tools.android.com/tech-docs/new-build-system/gradle-experimental
classpath 'com.android.tools.build:gradle-experimental:0.9.3'
classpath 'com.google.gms:google-services:3.0.0'
classpath 'com.google.gms:google-services:3.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files