Multi SIM support

This commit is contained in:
M66B 2015-12-06 13:57:02 +01:00
parent 51cd4b1686
commit 4091c413f8
2 changed files with 71 additions and 28 deletions

View File

@ -411,15 +411,24 @@ public class SinkholeService extends VpnService {
}
};
private BroadcastReceiver dataSIMChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Received " + intent);
Util.logExtras(intent);
reload(null, "SIM changed", SinkholeService.this);
}
};
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
private String last_generation = null;
private String last_operator = null;
private int last_international = -1;
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
if (state == TelephonyManager.DATA_CONNECTED) {
String current_generation = Util.getNetworkGeneration(networkType);
Log.i(TAG, "Data connected type=" + Util.getNetworkType(networkType) + " generation=" + current_generation);
String current_generation = Util.getNetworkGeneration(SinkholeService.this);
Log.i(TAG, "Data connected generation=" + current_generation);
if (last_generation == null || !last_generation.equals(current_generation)) {
Log.i(TAG, "New network generation=" + current_generation);
@ -437,13 +446,12 @@ public class SinkholeService extends VpnService {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String current_operator = tm.getNetworkOperator();
Log.i(TAG, "In service country=" + tm.getNetworkCountryIso() + " operator=" + current_operator);
int current_international = (Util.isInternational(SinkholeService.this) ? 1 : 0);
Log.i(TAG, "In service international=" + current_international);
if (last_operator == null || !last_operator.equals(current_operator)) {
Log.i(TAG, "New network operator=" + current_operator);
last_operator = current_operator;
if (last_international != current_international) {
Log.i(TAG, "New international=" + current_international);
last_international = current_international;
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SinkholeService.this);
if (prefs.getBoolean("national_roaming", false))
@ -491,6 +499,11 @@ public class SinkholeService extends VpnService {
ifConnectivity.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectivityChangedReceiver, ifConnectivity);
// Listen for data SIM changes
IntentFilter ifSIM = new IntentFilter();
ifSIM.addAction("android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED");
registerReceiver(dataSIMChangedReceiver, ifSIM);
// Listen for added applications
IntentFilter ifPackage = new IntentFilter();
ifPackage.addAction(Intent.ACTION_PACKAGE_ADDED);
@ -555,6 +568,7 @@ public class SinkholeService extends VpnService {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
unregisterReceiver(idleStateReceiver);
unregisterReceiver(connectivityChangedReceiver);
unregisterReceiver(dataSIMChangedReceiver);
unregisterReceiver(packageAddedReceiver);
if (phone_state) {

View File

@ -38,6 +38,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@ -101,6 +102,49 @@ public class Util {
return cm.isActiveNetworkMetered();
}
public static int getNetworkType(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return (ni == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN : ni.getSubtype());
}
public static String getNetworkGeneration(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return (ni != null && ni.getType() == ConnectivityManager.TYPE_MOBILE ? getNetworkGeneration(ni.getSubtype()) : null);
}
public static boolean isRoaming(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return (ni != null && ni.isRoaming());
}
public static boolean isInternational(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
int dataSubId = Settings.Global.getInt(context.getContentResolver(), "multi_sim_data_call", -1);
if (dataSubId >= 0) {
SubscriptionManager sm = SubscriptionManager.from(context);
SubscriptionInfo si = sm.getActiveSubscriptionInfo(dataSubId);
if (si != null && si.getCountryIso() != null)
try {
Method getNetworkCountryIso = tm.getClass().getMethod("getNetworkCountryIsoForSubscription", int.class);
getNetworkCountryIso.setAccessible(true);
String networkCountryIso = (String) getNetworkCountryIso.invoke(tm, dataSubId);
Log.d(TAG, "SIM=" + si.getCountryIso() + " network=" + networkCountryIso);
return !si.getCountryIso().equals(networkCountryIso);
} catch (Throwable ex) {
Log.w(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
sendCrashReport(ex, context);
}
}
}
return (tm.getSimCountryIso() == null ? true : !tm.getSimCountryIso().equals(tm.getNetworkCountryIso()));
}
public static String getNetworkGeneration(int networkType) {
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_1xRTT:
@ -131,8 +175,7 @@ public class Util {
}
}
public static String getNetworkType(int networkType) {
public static String getNetworkTypeName(int networkType) {
switch (networkType) {
// 2G
case TelephonyManager.NETWORK_TYPE_1xRTT:
@ -194,23 +237,6 @@ public class Util {
}
}
public static String getNetworkGeneration(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return (ni != null && ni.getType() == ConnectivityManager.TYPE_MOBILE ? getNetworkGeneration(ni.getSubtype()) : null);
}
public static boolean isRoaming(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
return (ni != null && ni.isRoaming());
}
public static boolean isInternational(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
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);
@ -380,6 +406,8 @@ public class Util {
.append(sm.getActiveSubscriptionInfoCountMax())
.append("\r\n");
int dataSubId = Settings.Global.getInt(context.getContentResolver(), "multi_sim_data_call", -1);
Method getNetworkCountryIso = null;
Method getNetworkOperator = null;
Method getNetworkOperatorName = null;
@ -413,6 +441,7 @@ public class Util {
.append(' ')
.append(si.getCarrierName())
.append(si.getDataRoaming() == SubscriptionManager.DATA_ROAMING_ENABLE ? " R" : "")
.append(si.getSubscriptionId() == dataSubId ? " *" : "")
.append("\r\n");
if (getNetworkCountryIso != null && getNetworkOperator != null && getNetworkOperatorName != null && isNetworkRoaming != null)
try {