Added phone state listener + permission checks

This commit is contained in:
M66B 2015-12-01 17:07:37 +01:00
parent 2c2480f052
commit 8bb0b9e256
4 changed files with 70 additions and 40 deletions

View File

@ -19,7 +19,6 @@ package eu.faircode.netguard;
Copyright 2015 by Marcel Bokhorst (M66B)
*/
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@ -28,8 +27,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.net.VpnService;
@ -45,7 +42,6 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SwitchCompat;
import android.telephony.TelephonyManager;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
@ -58,7 +54,6 @@ import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class ActivityMain extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -76,7 +71,6 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences
private static final int REQUEST_IAB = 2;
private static final int REQUEST_INVITE = 3;
private static final int REQUEST_LOGCAT = 4;
private static final int REQUEST_PERMISSIONS = 5;
private static final int MIN_SDK = Build.VERSION_CODES.LOLLIPOP;
@ -250,36 +244,6 @@ public class ActivityMain extends AppCompatActivity implements SharedPreferences
// Fill application list
updateApplicationList();
// Check runtime permissions
checkRuntimePermissions();
}
@TargetApi(Build.VERSION_CODES.M)
private void checkRuntimePermissions() {
List<String> listPermission = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) try {
PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_PERMISSIONS);
for (String permission : info.requestedPermissions) {
boolean granted = (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
Log.i(TAG, permission + '=' + granted);
if (!granted)
listPermission.add(permission);
}
} catch (PackageManager.NameNotFoundException ex) {
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
}
// Request runtime permissions
if (!listPermission.isEmpty())
requestPermissions(listPermission.toArray(new String[0]), REQUEST_PERMISSIONS);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
Log.i(TAG, "onRequestPermissionsResult");
for (int i = 0; i < permissions.length; i++)
Log.i(TAG, permissions[i] + '=' + (grantResults[i] == PackageManager.PERMISSION_GRANTED));
}
@Override

View File

@ -19,19 +19,24 @@ package eu.faircode.netguard;
Copyright 2015 by Marcel Bokhorst (M66B)
*/
import android.Manifest;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;
import android.util.Log;
@ -57,16 +62,22 @@ import javax.xml.parsers.SAXParserFactory;
public class ActivitySettings extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "NetGuard.Settings";
private SwitchPreference pref_national_roaming = null;
private Preference pref_technical = null;
private static final int REQUEST_EXPORT = 1;
private static final int REQUEST_IMPORT = 2;
private static final int REQUEST_READ_PHONE_STATE = 3;
private static final Intent INTENT_VPN_SETTINGS = new Intent("android.net.vpn.SETTINGS");
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
setTheme(prefs.getBoolean("dark_theme", false) ? R.style.AppThemeDark : R.style.AppTheme);
// Check if permission was revoked
if (prefs.getBoolean("national_roaming", false) && !Util.hasPhoneStatePermission(this))
prefs.edit().putBoolean("national_roaming", false).apply();
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new FragmentSettings()).commit();
@ -105,6 +116,8 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
}
public void setup(PreferenceScreen screen) {
pref_national_roaming = (SwitchPreference) screen.findPreference("national_roaming");
Preference pref_export = screen.findPreference("export");
pref_export.setEnabled(getIntentCreateDocument().resolveActivity(getPackageManager()) != null);
pref_export.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@ -148,6 +161,7 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
}
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onSharedPreferenceChanged(SharedPreferences prefs, String name) {
if ("whitelist_wifi".equals(name) ||
"screen_wifi".equals(name))
@ -155,11 +169,19 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
else if ("whitelist_other".equals(name) ||
"screen_other".equals(name) ||
"whitelist_roaming".equals(name) ||
"national_roaming".equals(name))
"whitelist_roaming".equals(name))
SinkholeService.reload("other", this);
else if ("use_metered".equals(name) ||
else if ("national_roaming".equals(name)) {
if (prefs.getBoolean(name, false)) {
if (Util.hasPhoneStatePermission(this))
SinkholeService.reload("other", this);
else
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_READ_PHONE_STATE);
} else
SinkholeService.reload("other", this);
} else if ("use_metered".equals(name) ||
"manage_system".equals(name))
SinkholeService.reload(null, this);
@ -167,6 +189,18 @@ public class ActivitySettings extends AppCompatActivity implements SharedPrefere
recreate();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_READ_PHONE_STATE)
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
SinkholeService.reload("other", this);
else {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putBoolean("national_roaming", false).apply();
pref_national_roaming.setChecked(false);
}
}
private BroadcastReceiver interactiveStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {

View File

@ -43,6 +43,9 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.io.FileInputStream;
@ -56,6 +59,7 @@ public class SinkholeService extends VpnService {
private boolean last_connected;
private boolean last_metered;
private boolean phone_state = false;
private ParcelFileDescriptor vpn = null;
private boolean debug = false;
private Thread debugThread = null;
@ -386,6 +390,15 @@ public class SinkholeService extends VpnService {
}
};
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
super.onServiceStateChanged(serviceState);
Log.i(TAG, "Service state=" + serviceState);
reload(null, SinkholeService.this);
}
};
private BroadcastReceiver packageAddedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@ -429,6 +442,13 @@ public class SinkholeService extends VpnService {
ifPackage.addAction(Intent.ACTION_PACKAGE_ADDED);
ifPackage.addDataScheme("package");
registerReceiver(packageAddedReceiver, ifPackage);
if (Util.hasPhoneStatePermission(this)) {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
phone_state = true;
Log.i(TAG, "Listening to service state changes");
}
}
@Override
@ -489,6 +509,11 @@ public class SinkholeService extends VpnService {
unregisterReceiver(connectivityChangedReceiver);
unregisterReceiver(packageAddedReceiver);
if (phone_state) {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
if (vpn != null) {
stopDebug();
stopVPN(vpn);

View File

@ -19,6 +19,7 @@ package eu.faircode.netguard;
Copyright 2015 by Marcel Bokhorst (M66B)
*/
import android.Manifest;
import android.app.ApplicationErrorReport;
import android.content.Context;
import android.content.Intent;
@ -36,7 +37,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
@ -103,6 +103,13 @@ public class Util {
return (tm.getSimCountryIso() == null ? true : !tm.getSimCountryIso().equals(tm.getNetworkCountryIso()));
}
public static boolean hasPhoneStatePermission(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
return (context.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED);
else
return true;
}
public static boolean isInteractive(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return pm.isInteractive();