diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d772a74d..e37efbded 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* **[Breaking change]** Remove `AppCenter.setCustomProperties` API.
* **[Fix]** Remove `android.support.test.InstrumentationRegistry` string that caused an error when checking applications on availability of android support libraries.
+* **[Feature]** Add method to manually set the country code `AppCenter.setCountryCode(string)`.
### App Center Analytics
diff --git a/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/MainActivity.java b/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/MainActivity.java
index 381ccb9cc..e235c1a04 100644
--- a/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/MainActivity.java
+++ b/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/MainActivity.java
@@ -121,6 +121,13 @@ static void startAppCenter(Application application, String startTypeString) {
// Analytics.enableManualSessionTracker();
}
+ /* Set country code. */
+ String countryCode = MainActivity.sSharedPreferences.getString(application.getString(R.string.country_code_key), null);
+ if (countryCode != null) {
+ // TODO uncomment after release
+ // AppCenter.setCountryCode(countryCode);
+ }
+
/* Set the track explicitly only if we set it in settings, to test the initial public by default at first launch. */
int savedTrack = sSharedPreferences.getInt(application.getString(R.string.appcenter_distribute_track_state_key), 0);
if (savedTrack != 0) {
diff --git a/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/SettingsActivity.java b/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/SettingsActivity.java
index 9626ee960..00c944315 100644
--- a/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/SettingsActivity.java
+++ b/apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/SettingsActivity.java
@@ -107,6 +107,34 @@ public boolean isEnabled() {
return AppCenter.isEnabled().get();
}
});
+ initClickableSetting(R.string.country_code_key, MainActivity.sSharedPreferences.getString(getActivity().getString(R.string.country_code_key), ""), new Preference.OnPreferenceClickListener() {
+
+ @Override
+ public boolean onPreferenceClick(final Preference preference) {
+ final EditText input = new EditText(getActivity());
+ input.setInputType(InputType.TYPE_CLASS_TEXT);
+ input.setHint(R.string.country_code_title);
+ input.setText(MainActivity.sSharedPreferences.getString(getActivity().getString(R.string.country_code_key), ""));
+ input.setSelection(input.getText().length());
+ new AlertDialog.Builder(getActivity()).setTitle(R.string.storage_size_title).setView(input)
+ .setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
+
+ @SuppressLint("CommitPrefEdits")
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ MainActivity.sSharedPreferences
+ .edit()
+ .putString(getActivity().getString(R.string.country_code_key), input.getText().toString())
+ .apply();
+ preference.setSummary(input.getText());
+ Toast.makeText(getActivity(), getActivity().getString(R.string.country_code_save_message), Toast.LENGTH_SHORT).show();
+ }
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .create().show();
+ return true;
+ }
+ });
initClickableSetting(R.string.storage_size_key, Formatter.formatFileSize(getActivity(), MainActivity.sSharedPreferences.getLong(MAX_STORAGE_SIZE_KEY, DEFAULT_MAX_STORAGE_SIZE)), new Preference.OnPreferenceClickListener() {
@Override
diff --git a/apps/sasquatch/src/main/res/values/settings.xml b/apps/sasquatch/src/main/res/values/settings.xml
index c202082d0..1ee12aa7f 100644
--- a/apps/sasquatch/src/main/res/values/settings.xml
+++ b/apps/sasquatch/src/main/res/values/settings.xml
@@ -12,6 +12,10 @@
storage_size_key
Storage Max Size
+ country_code_key
+ Country Code
+ Country code value will be applied after the application restart.
+
storage_file_size_key
Storage File Size
diff --git a/apps/sasquatch/src/main/res/xml/settings.xml b/apps/sasquatch/src/main/res/xml/settings.xml
index 79be12162..a68dde634 100644
--- a/apps/sasquatch/src/main/res/xml/settings.xml
+++ b/apps/sasquatch/src/main/res/xml/settings.xml
@@ -8,6 +8,9 @@
+
diff --git a/sdk/appcenter/src/main/java/com/microsoft/appcenter/AppCenter.java b/sdk/appcenter/src/main/java/com/microsoft/appcenter/AppCenter.java
index d6fa46743..cae518066 100644
--- a/sdk/appcenter/src/main/java/com/microsoft/appcenter/AppCenter.java
+++ b/sdk/appcenter/src/main/java/com/microsoft/appcenter/AppCenter.java
@@ -288,6 +288,15 @@ public static void setLogUrl(String logUrl) {
getInstance().setInstanceLogUrl(logUrl);
}
+ /**
+ * Set the two-letter ISO country code to send to the backend.
+ *
+ * @param countryCode the two-letter ISO country code. See https://www.iso.org/obp/ui/#search
for more information.
+ */
+ public static void setCountryCode(String countryCode) {
+ DeviceInfoHelper.setCountryCode(countryCode);
+ }
+
/**
* Get the current version of App Center SDK.
*
diff --git a/sdk/appcenter/src/main/java/com/microsoft/appcenter/utils/DeviceInfoHelper.java b/sdk/appcenter/src/main/java/com/microsoft/appcenter/utils/DeviceInfoHelper.java
index d87ab9a15..d58c57ff3 100644
--- a/sdk/appcenter/src/main/java/com/microsoft/appcenter/utils/DeviceInfoHelper.java
+++ b/sdk/appcenter/src/main/java/com/microsoft/appcenter/utils/DeviceInfoHelper.java
@@ -17,7 +17,6 @@
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Surface;
-import android.view.WindowManager;
import com.microsoft.appcenter.AppCenter;
import com.microsoft.appcenter.ingestion.models.Device;
@@ -41,6 +40,11 @@ public class DeviceInfoHelper {
*/
private static WrapperSdk sWrapperSdk;
+ /**
+ * Country code.
+ */
+ private static String mCountryCode;
+
/**
* Gets device information.
*
@@ -81,6 +85,11 @@ public static synchronized Device getDeviceInfo(Context context) throws DeviceIn
AppCenterLog.error(AppCenter.LOG_TAG, "Cannot retrieve carrier info", e);
}
+ /* Set country code. */
+ if (mCountryCode != null) {
+ device.setCarrierCountry(mCountryCode);
+ }
+
/* Locale. */
device.setLocale(Locale.getDefault().toString());
@@ -180,6 +189,20 @@ public static synchronized void setWrapperSdk(WrapperSdk wrapperSdk) {
sWrapperSdk = wrapperSdk;
}
+ /**
+ * Set the two-letter ISO country code.
+ *
+ * @param countryCode the two-letter ISO country code.
+ */
+ public static void setCountryCode(String countryCode) {
+ if (countryCode != null && countryCode.length() != 2) {
+ AppCenterLog.error(AppCenterLog.LOG_TAG, "App Center accepts only the two-letter ISO country code.");
+ return;
+ }
+ mCountryCode = countryCode;
+ AppCenterLog.debug(AppCenterLog.LOG_TAG, String.format("Set country code: %s", countryCode));
+ }
+
/**
* Thrown when {@link DeviceInfoHelper} cannot retrieve device information from devices
*/
diff --git a/sdk/appcenter/src/test/java/com/microsoft/appcenter/AppCenterTest.java b/sdk/appcenter/src/test/java/com/microsoft/appcenter/AppCenterTest.java
index 31848f31d..b3856b33a 100644
--- a/sdk/appcenter/src/test/java/com/microsoft/appcenter/AppCenterTest.java
+++ b/sdk/appcenter/src/test/java/com/microsoft/appcenter/AppCenterTest.java
@@ -845,6 +845,18 @@ public void setWrapperSdkTest() {
verify(mChannel).invalidateDeviceCache();
}
+ @Test
+ public void setCountryCode() {
+
+ /* Set country code. */
+ String expectedCountryCode = "aa";
+ AppCenter.setCountryCode(expectedCountryCode);
+
+ /* Check that method was called. */
+ verifyStatic();
+ DeviceInfoHelper.setCountryCode(eq(expectedCountryCode));
+ }
+
@Test
public void setDefaultLogLevelRelease() {
mApplicationInfo.flags = 0;
diff --git a/sdk/appcenter/src/test/java/com/microsoft/appcenter/utils/DeviceInfoHelperTest.java b/sdk/appcenter/src/test/java/com/microsoft/appcenter/utils/DeviceInfoHelperTest.java
index 861b2883c..2c2cc15e8 100644
--- a/sdk/appcenter/src/test/java/com/microsoft/appcenter/utils/DeviceInfoHelperTest.java
+++ b/sdk/appcenter/src/test/java/com/microsoft/appcenter/utils/DeviceInfoHelperTest.java
@@ -84,6 +84,7 @@ public class DeviceInfoHelperTest {
@Before
public void setup() {
+ DeviceInfoHelper.setCountryCode(null);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
}
@@ -290,4 +291,76 @@ public void getDeviceInfoMissingScreenSize() throws DeviceInfoHelper.DeviceInfoE
verifyStatic();
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(Exception.class));
}
+
+ @Test
+ public void setCountryCode() throws DeviceInfoHelper.DeviceInfoException, PackageManager.NameNotFoundException {
+
+ /* Mock system calls. */
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
+ when(mTelephonyManager.getNetworkOperatorName()).thenReturn("");
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+
+ /* Set invalid country code. */
+ String expectedCountryCode = "aa";
+ DeviceInfoHelper.setCountryCode(expectedCountryCode);
+
+ /* Get device info. */
+ Device device = DeviceInfoHelper.getDeviceInfo(mContext);
+ assertEquals(device.getCarrierCountry(), expectedCountryCode);
+ }
+
+ @Test
+ public void setNullCountryCode() throws DeviceInfoHelper.DeviceInfoException, PackageManager.NameNotFoundException {
+
+ /* Mock system calls. */
+ String expectedCountryCode = "aa";
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn(expectedCountryCode);
+ when(mTelephonyManager.getNetworkOperatorName()).thenReturn(expectedCountryCode);
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+
+ /* Set country code. */
+ DeviceInfoHelper.setCountryCode(null);
+
+ /* Verify that system method was called. */
+ Device device = DeviceInfoHelper.getDeviceInfo(mContext);
+ verify(mTelephonyManager).getNetworkCountryIso();
+ assertEquals(device.getCarrierCountry(), expectedCountryCode);
+ }
+
+ @Test
+ public void setShortCountryCode() throws DeviceInfoHelper.DeviceInfoException, PackageManager.NameNotFoundException {
+ verifyCountryCodeWithInvalidLength("a");
+ }
+
+ @Test
+ public void setLongCountryCode() throws DeviceInfoHelper.DeviceInfoException, PackageManager.NameNotFoundException {
+ verifyCountryCodeWithInvalidLength("abc");
+ }
+
+ public void verifyCountryCodeWithInvalidLength(String countryCode) throws DeviceInfoHelper.DeviceInfoException, PackageManager.NameNotFoundException {
+
+ /* Mock system calls. */
+ String expectedCountryCode = "aa";
+ when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn(expectedCountryCode);
+ when(mTelephonyManager.getNetworkOperatorName()).thenReturn(expectedCountryCode);
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+
+ /* Mocking instances. */
+ mockStatic(AppCenterLog.class);
+
+ /* Set invalid country code. */
+ DeviceInfoHelper.setCountryCode(countryCode);
+
+ /* Verify that log was called.*/
+ verifyStatic();
+ AppCenterLog.error(eq(AppCenter.LOG_TAG), eq("App Center accepts only the two-letter ISO country code."));
+
+ /* Verify that invalid value wasn't set. */
+ Device device = DeviceInfoHelper.getDeviceInfo(mContext);
+ assertEquals(device.getCarrierCountry(), expectedCountryCode);
+ verify(mTelephonyManager).getNetworkCountryIso();
+ }
}