1package eu.siacs.conversations.utils;
 2
 3import android.content.Context;
 4import android.telephony.TelephonyManager;
 5import android.util.Log;
 6
 7import androidx.core.content.ContextCompat;
 8
 9import org.osmdroid.util.GeoPoint;
10
11import java.io.BufferedReader;
12import java.io.IOException;
13import java.io.InputStreamReader;
14import java.util.Locale;
15
16import eu.siacs.conversations.Config;
17import eu.siacs.conversations.R;
18
19public class LocationProvider {
20
21    public static final GeoPoint FALLBACK = new GeoPoint(0.0, 0.0);
22
23    public static String getUserCountry(final Context context) {
24        return getUserCountry(context, false);
25    }
26
27    public static String getUserCountry(final Context context, boolean preferNetwork) {
28        try {
29            final TelephonyManager tm = ContextCompat.getSystemService(context, TelephonyManager.class);
30            if (tm == null) {
31                return getUserCountryFallback();
32            }
33            Log.d(Config.LOGTAG, "SIM Operator: " + tm.getSimOperator());
34            final String simCountry = "20801".equals(tm.getSimOperator()) || "26001".equals(tm.getSimOperator()) ? "us" : tm.getSimCountryIso();
35            final String networkCountry = tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA ? null : tm.getNetworkCountryIso(); // if device is not 3G would be unreliable
36            if (preferNetwork && networkCountry != null && networkCountry.length() == 2) {
37                return networkCountry.toUpperCase(Locale.US);
38            }
39
40            if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
41                return simCountry.toUpperCase(Locale.US);
42            }
43
44            return getUserCountryFallback();
45        } catch (final Exception e) {
46            return getUserCountryFallback();
47        }
48    }
49
50    private static String getUserCountryFallback() {
51        final Locale locale = Locale.getDefault();
52        return locale.getCountry();
53    }
54
55    public static GeoPoint getGeoPoint(final Context context) {
56        return getGeoPoint(context, getUserCountry(context));
57    }
58
59
60    public static synchronized GeoPoint getGeoPoint(final Context context, final String country) {
61        try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.countries)))) {
62            String line;
63            while ((line = reader.readLine()) != null) {
64                final String[] parts = line.split("\\s+", 4);
65                if (parts.length == 4) {
66                    if (country.equalsIgnoreCase(parts[0])) {
67                        try {
68                            return new GeoPoint(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]));
69                        } catch (final NumberFormatException e) {
70                            return FALLBACK;
71                        }
72                    }
73                }
74            }
75        } catch (final IOException e) {
76            Log.d(Config.LOGTAG, "unable to parse country->geo map", e);
77        }
78        return FALLBACK;
79    }
80
81}