Skip to content

Commit 7fffffe

Browse files
Merge pull request #1708 from microsoft/develop
Version 5.0.3
2 parents de8553f + 46e6bf2 commit 7fffffe

File tree

18 files changed

+318
-16
lines changed

18 files changed

+318
-16
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# App Center SDK for Android Change Log
22

3-
## Version 5.0.2 (In development)
3+
## Version 5.0.3 (In development)
4+
5+
## Version 5.0.2
46

57
### AppCenter
68

apps/sasquatch/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
flavorDimensions "dependency", "distribute"
1515

1616
defaultConfig {
17-
versionCode 300
18-
versionName "5.0.1"
17+
versionCode 302
18+
versionName "5.0.3"
1919
externalNativeBuild {
2020
ndkBuild {
2121
arguments "NDK_APPLICATION_MK=Application.mk", "V=1"
@@ -100,7 +100,7 @@ dependencies {
100100
projectDependencyImplementation project(':sdk:appcenter-analytics')
101101
projectDependencyImplementation project(':sdk:appcenter-crashes')
102102

103-
def appCenterSdkVersion = "5.0.1"
103+
def appCenterSdkVersion = "5.0.2"
104104
mavenCentralDependencyImplementation "com.microsoft.appcenter:appcenter-analytics:${appCenterSdkVersion}"
105105
mavenCentralDependencyImplementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
106106

apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/MainActivity.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ static void startAppCenter(Application application, String startTypeString) {
132132
AppCenter.setCountryCode(countryCode);
133133
}
134134

135+
// TODO: uncomment this code after release sdk to maven
136+
// /* Set data residency region. */
137+
// String dataResidencyRegion = MainActivity.sSharedPreferences.getString(application.getString(R.string.data_residency_region_key), null);
138+
// if (dataResidencyRegion != null) {
139+
// AppCenter.setDataResidencyRegion(dataResidencyRegion);
140+
// }
141+
135142
/* Set the track explicitly only if we set it in settings, to test the initial public by default at first launch. */
136143
int savedTrack = sSharedPreferences.getInt(application.getString(R.string.appcenter_distribute_track_state_key), 0);
137144
if (savedTrack != 0) {

apps/sasquatch/src/main/java/com/microsoft/appcenter/sasquatch/activities/SettingsActivity.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,34 @@ public void onClick(DialogInterface dialog, int which) {
136136
return true;
137137
}
138138
});
139+
initClickableSetting(R.string.data_residency_region_key, MainActivity.sSharedPreferences.getString(getActivity().getString(R.string.data_residency_region_key), null), new Preference.OnPreferenceClickListener() {
140+
141+
@Override
142+
public boolean onPreferenceClick(final Preference preference) {
143+
final EditText input = new EditText(getActivity());
144+
input.setInputType(InputType.TYPE_CLASS_TEXT);
145+
input.setHint(R.string.data_residency_region_title);
146+
input.setText(MainActivity.sSharedPreferences.getString(getActivity().getString(R.string.data_residency_region_key), null));
147+
input.setSelection(input.getText().length());
148+
new AlertDialog.Builder(getActivity()).setTitle(R.string.data_residency_region_title).setView(input)
149+
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
150+
151+
@SuppressLint("CommitPrefEdits")
152+
@Override
153+
public void onClick(DialogInterface dialog, int which) {
154+
MainActivity.sSharedPreferences
155+
.edit()
156+
.putString(getActivity().getString(R.string.data_residency_region_key), input.getText().toString())
157+
.apply();
158+
preference.setSummary(input.getText());
159+
Toast.makeText(getActivity(), getActivity().getString(R.string.data_residency_region_save_message), Toast.LENGTH_SHORT).show();
160+
}
161+
})
162+
.setNegativeButton(R.string.cancel, null)
163+
.create().show();
164+
return true;
165+
}
166+
});
139167
initClickableSetting(R.string.storage_size_key, Formatter.formatFileSize(getActivity(), MainActivity.sSharedPreferences.getLong(MAX_STORAGE_SIZE_KEY, DEFAULT_MAX_STORAGE_SIZE)), new Preference.OnPreferenceClickListener() {
140168

141169
@Override

apps/sasquatch/src/main/res/values/settings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
<string name="country_code_title" tools:ignore="MissingTranslation">Country Code</string>
1717
<string name="country_code_save_message" tools:ignore="MissingTranslation">Country code value will be applied after the application restart.</string>
1818

19+
<string name="data_residency_region_key" tools:ignore="MissingTranslation">data_residency_region</string>
20+
<string name="data_residency_region_title" tools:ignore="MissingTranslation">Data residency region</string>
21+
<string name="data_residency_region_save_message" tools:ignore="MissingTranslation">Data residency region value will be applied after the application restart.</string>
22+
1923
<string name="storage_file_size_key" tools:ignore="MissingTranslation">storage_file_size_key</string>
2024
<string name="storage_file_size_title" tools:ignore="MissingTranslation">Storage File Size</string>
2125

apps/sasquatch/src/main/res/xml/settings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
<Preference
1212
android:key="@string/country_code_key"
1313
android:title="@string/country_code_title" />
14+
<EditTextPreference
15+
android:key="@string/data_residency_region_key"
16+
android:selectAllOnFocus="false"
17+
android:singleLine="false"
18+
android:title="@string/data_residency_region_title" />
1419
<Preference
1520
android:key="@string/storage_size_key"
1621
android:title="@string/storage_size_title" />

sdk/appcenter-crashes/src/androidTest/java/com/microsoft/appcenter/crashes/utils/ErrorLogHelperAndroidTest.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55

66
package com.microsoft.appcenter.crashes.utils;
77

8+
import static org.junit.Assert.assertEquals;
9+
import static org.junit.Assert.assertFalse;
10+
import static org.junit.Assert.assertNotNull;
11+
import static org.junit.Assert.assertNull;
12+
import static org.junit.Assert.assertTrue;
13+
814
import androidx.test.platform.app.InstrumentationRegistry;
915

1016
import com.microsoft.appcenter.Constants;
@@ -19,12 +25,6 @@
1925
import java.io.File;
2026
import java.util.UUID;
2127

22-
import static org.junit.Assert.assertEquals;
23-
import static org.junit.Assert.assertFalse;
24-
import static org.junit.Assert.assertNotNull;
25-
import static org.junit.Assert.assertNull;
26-
import static org.junit.Assert.assertTrue;
27-
2828
@SuppressWarnings("unused")
2929
public class ErrorLogHelperAndroidTest {
3030

@@ -170,4 +170,19 @@ public void parseDevice() {
170170
assertNotNull(device4);
171171
assertNull(userId4);
172172
}
173+
174+
@Test
175+
public void parseDataResidencyRegion() {
176+
String mockDataResidencyRegion = "mockRegion";
177+
String mockContextInformation = "{\"dataResidencyRegion\":\"" + mockDataResidencyRegion + "\"}";
178+
String result = ErrorLogHelper.parseDataResidencyRegion(mockContextInformation);
179+
assertEquals(mockDataResidencyRegion, result);
180+
}
181+
182+
@Test()
183+
public void parseDataResidencyRegionIncorrectJson() {
184+
String invalidJson = "invalidJson";
185+
String result = ErrorLogHelper.parseDataResidencyRegion(invalidJson);
186+
assertNull(result);
187+
}
173188
}

sdk/appcenter-crashes/src/main/java/com/microsoft/appcenter/crashes/Crashes.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import androidx.annotation.WorkerThread;
1616

1717
import com.microsoft.appcenter.AbstractAppCenterService;
18+
import com.microsoft.appcenter.AppCenter;
1819
import com.microsoft.appcenter.Constants;
1920
import com.microsoft.appcenter.Flags;
2021
import com.microsoft.appcenter.channel.Channel;
@@ -639,6 +640,8 @@ private synchronized UUID queueException(@NonNull final ExceptionModelBuilder ex
639640
final String userId = UserIdContext.getInstance().getUserId();
640641
final UUID errorId = UUID.randomUUID();
641642
final Map<String, String> validatedProperties = ErrorLogHelper.validateProperties(properties, "HandledError");
643+
final String dataResidencyRegion = AppCenter.getDataResidencyRegion();
644+
642645
post(new Runnable() {
643646

644647
@Override
@@ -648,11 +651,17 @@ public void run() {
648651
HandledErrorLog errorLog = new HandledErrorLog();
649652
errorLog.setId(errorId);
650653
errorLog.setUserId(userId);
654+
errorLog.setDataResidencyRegion(dataResidencyRegion);
651655
errorLog.setException(exceptionModelBuilder.buildExceptionModel());
652656
errorLog.setProperties(validatedProperties);
653657
mChannel.enqueue(errorLog, ERROR_GROUP, Flags.DEFAULTS);
654658

655659
/* Then attachments if any. */
660+
if (attachments != null) {
661+
for (ErrorAttachmentLog attachment : attachments) {
662+
attachment.setDataResidencyRegion(dataResidencyRegion);
663+
}
664+
}
656665
sendErrorAttachment(errorId, attachments);
657666
}
658667
});
@@ -780,6 +789,7 @@ private void processSingleMinidump(File minidumpFile, File minidumpFolder) {
780789
errorLog.setProcessName("");
781790
try {
782791
String savedUserId = ErrorLogHelper.getStoredUserInfo(minidumpFolder);
792+
String dataResidencyRegion = ErrorLogHelper.getStoredDataResidencyRegion(minidumpFolder);
783793
Device savedDeviceInfo = ErrorLogHelper.getStoredDeviceInfo(minidumpFolder);
784794
if (savedDeviceInfo == null) {
785795

@@ -792,6 +802,7 @@ private void processSingleMinidump(File minidumpFile, File minidumpFolder) {
792802
}
793803
errorLog.setDevice(savedDeviceInfo);
794804
errorLog.setUserId(savedUserId);
805+
errorLog.setDataResidencyRegion(dataResidencyRegion);
795806
saveErrorLogFiles(new NativeException(), errorLog);
796807
if (!minidumpFile.renameTo(dest)) {
797808
throw new IOException("Failed to move file");

sdk/appcenter-crashes/src/main/java/com/microsoft/appcenter/crashes/utils/ErrorLogHelper.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import androidx.annotation.Nullable;
1515
import androidx.annotation.VisibleForTesting;
1616

17+
import com.microsoft.appcenter.AppCenter;
1718
import com.microsoft.appcenter.Constants;
1819
import com.microsoft.appcenter.crashes.Crashes;
1920
import com.microsoft.appcenter.crashes.ingestion.models.Exception;
@@ -144,6 +145,11 @@ public class ErrorLogHelper {
144145
@VisibleForTesting
145146
static String DEVICE_INFO_KEY = "DEVICE_INFO";
146147

148+
/**
149+
* Key for data residency region.
150+
*/
151+
private static final String DATA_RESIDENCY_REGION_KEY = "dataResidencyRegion";
152+
147153
/**
148154
* Key for saving userId to JSON.
149155
*/
@@ -168,6 +174,9 @@ public static ManagedErrorLog createErrorLog(@NonNull Context context, @NonNull
168174
/* Set user identifier. */
169175
errorLog.setUserId(UserIdContext.getInstance().getUserId());
170176

177+
/* Set data residency region. */
178+
errorLog.setDataResidencyRegion(AppCenter.getDataResidencyRegion());
179+
171180
/* Snapshot device properties. */
172181
try {
173182
errorLog.setDevice(DeviceInfoHelper.getDeviceInfo(context));
@@ -287,6 +296,7 @@ public static synchronized File getNewMinidumpSubfolderWithContextData(Context c
287296
try {
288297
Device deviceInfo = DeviceInfoHelper.getDeviceInfo(context);
289298
String userIdContext = UserIdContext.getInstance().getUserId();
299+
String dataResidencyRegion = AppCenter.getDataResidencyRegion();
290300
deviceInfo.setWrapperSdkName(WRAPPER_SDK_NAME_NDK);
291301

292302
/* To JSON. */
@@ -296,6 +306,7 @@ public static synchronized File getNewMinidumpSubfolderWithContextData(Context c
296306
writer.endObject();
297307
String deviceInfoString = writer.toString();
298308
JSONObject jsonObject = new JSONObject();
309+
jsonObject.put(DATA_RESIDENCY_REGION_KEY, dataResidencyRegion);
299310
jsonObject.put(DEVICE_INFO_KEY, deviceInfoString);
300311
jsonObject.put(USER_ID_KEY, userIdContext);
301312

@@ -371,6 +382,21 @@ public static String getStoredUserInfo(File logFolder) {
371382
return parseUserId(userInformationString);
372383
}
373384

385+
/**
386+
* Get data residency region.
387+
*
388+
* @param logFolder folder where to look for stored data residency region.
389+
* @return a data residency region or null.
390+
*/
391+
@Nullable
392+
public static String getStoredDataResidencyRegion(File logFolder) {
393+
String context = getContextInformation(logFolder);
394+
if (context == null) {
395+
return null;
396+
}
397+
return parseDataResidencyRegion(context);
398+
}
399+
374400
/**
375401
* Get data about userId and deviceInfo in JSON format.
376402
* @param logFolder - path to folder where placed file with data about userId and deviceId.
@@ -439,6 +465,24 @@ static Device parseDevice(String contextInformation) {
439465
return null;
440466
}
441467

468+
/**
469+
* Look for 'dataResidencyRegion' data in file inside the minidump folder and parse it.
470+
* @param contextInformation - data with information about userId.
471+
* @return dataResidencyRegion or null.
472+
*/
473+
@VisibleForTesting
474+
static String parseDataResidencyRegion(String contextInformation) {
475+
try {
476+
JSONObject jsonObject = new JSONObject(contextInformation);
477+
if (jsonObject.has(DATA_RESIDENCY_REGION_KEY)) {
478+
return jsonObject.getString(DATA_RESIDENCY_REGION_KEY);
479+
}
480+
} catch (JSONException e) {
481+
AppCenterLog.error(Crashes.LOG_TAG, "Failed to deserialize data residency region.", e);
482+
}
483+
return null;
484+
}
485+
442486
/**
443487
* Remove the minidump sub-folders from previous sessions in the 'minidump/new' folder.
444488
* Minidumps from these folders should already be moved to the 'minidump/pending' folder,

sdk/appcenter-crashes/src/test/java/com/microsoft/appcenter/crashes/utils/ErrorLogHelperTest.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,26 +428,30 @@ public void getStoredDeviceInfo() throws IOException {
428428
}
429429

430430
@Test
431-
public void getStoredDeviceInfoAndUserIdNull() {
431+
public void getStoredMinidumpFileContentNull() {
432432
File minidumpFolder = mock(File.class);
433433
when(minidumpFolder.listFiles(any(FilenameFilter.class))).thenReturn(null);
434434
Device storedDeviceInfo = ErrorLogHelper.getStoredDeviceInfo(minidumpFolder);
435435
String storedUserId = ErrorLogHelper.getStoredUserInfo(minidumpFolder);
436+
String dataResidencyRegion = ErrorLogHelper.getStoredDataResidencyRegion(minidumpFolder);
436437
assertNull(storedDeviceInfo);
437438
assertNull(storedUserId);
439+
assertNull(dataResidencyRegion);
438440
}
439441

440442
@Test
441-
public void getStoredDeviceInfoAndUserIdEmpty() throws IOException {
443+
public void getStoredMinidumpFileContentEmpty() throws IOException {
442444
File minidumpFolder = mTemporaryFolder.newFolder("minidump");
443445
Device storedDeviceInfo = ErrorLogHelper.getStoredDeviceInfo(minidumpFolder);
444446
String storedUserId = ErrorLogHelper.getStoredUserInfo(minidumpFolder);
447+
String dataResidencyRegion = ErrorLogHelper.getStoredDataResidencyRegion(minidumpFolder);
445448
assertNull(storedDeviceInfo);
446449
assertNull(storedUserId);
450+
assertNull(dataResidencyRegion);
447451
}
448452

449453
@Test
450-
public void getStoredDeviceInfoAndUserInfoCannotRead() throws IOException {
454+
public void getStoredMinidumpFileContentCannotRead() throws IOException {
451455
File minidumpFolder = mTemporaryFolder.newFolder("minidump");
452456
File deviceInfoFile = new File(minidumpFolder, ErrorLogHelper.DEVICE_INFO_FILE);
453457
assertTrue(deviceInfoFile.createNewFile());
@@ -457,6 +461,8 @@ public void getStoredDeviceInfoAndUserInfoCannotRead() throws IOException {
457461
assertNull(storedDeviceInfo);
458462
String userInfo = ErrorLogHelper.getStoredUserInfo(minidumpFolder);
459463
assertNull(userInfo);
464+
String dataResidencyRegion = ErrorLogHelper.getStoredDataResidencyRegion(minidumpFolder);
465+
assertNull(dataResidencyRegion);
460466
}
461467

462468
@Test

0 commit comments

Comments
 (0)