Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

staging -> main [Core-2.3.0] [Lifecycle-2.0.4] #517

Merged
merged 34 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
49868eb
Fix edge case that may cause a stale appId override
prudrabhat May 16, 2023
bb9c36c
Merge remote-tracking branch 'upstream/dev' into fix_stale_appid_over…
prudrabhat May 16, 2023
3c05635
Merge remote-tracking branch 'upstream/dev' into fix_stale_appid_over…
prudrabhat Jun 12, 2023
d92c08c
Add tests and fix docs
prudrabhat Jun 12, 2023
e8b2815
Merge remote-tracking branch 'upstream/dev' into fix_stale_appid_over…
prudrabhat Jun 12, 2023
d3f572e
do dismiss tracking and back press tracking if a back press occurred
rymorale Jun 20, 2023
469a49e
Use internal flag and persisted id for disambiguation
prudrabhat Jun 20, 2023
83e01bb
Merge remote-tracking branch 'upstream/dev' into fix_stale_appid_over…
prudrabhat Jun 20, 2023
3cec20e
fix message placement and rounded corners on api 22 and below
rymorale Jun 22, 2023
e9492b5
fix style error
rymorale Jun 22, 2023
3fb7de2
check if objects used for displaying an iam are null before cleaning …
rymorale Jun 27, 2023
9b27d31
Merge branch 'backpress-npe-fix' into update-on-back-pressed-handling
rymorale Jun 27, 2023
27d693c
Merge pull request #492 from prudrabhat/fix_stale_appid_override
prudrabhat Jun 27, 2023
c84aa86
restore inadvertent removal of listener.onDismiss
rymorale Jun 27, 2023
a68ae40
ensure views are cleaned even if the dismiss animation is not started
rymorale Jun 28, 2023
f3dec12
fix double back press event, cleanup dismiss
rymorale Jun 28, 2023
37d5bb0
Merge remote-tracking branch 'upstream/main' into update-on-back-pres…
rymorale Jun 30, 2023
4bf8b0f
remove version check when setting the webview alpha
rymorale Jul 11, 2023
351b408
fix code formatting, remove unused import
rymorale Jul 11, 2023
86a6e5a
Merge pull request #500 from rymorale/update-on-back-pressed-handling
rymorale Jul 14, 2023
3de11f8
Merge pull request #511 from adobe/main
praveek Jul 18, 2023
ea5e98b
Update services to query system locale
praveek Jul 19, 2023
5d05770
Lifecycle updates for system locale
praveek Jul 19, 2023
7952e40
Fix review comments
praveek Jul 19, 2023
b6617f1
Refactor logic around fetching locale
praveek Jul 19, 2023
40ad957
Merge pull request #513 from praveek/dev
praveek Jul 19, 2023
2685f32
Reset dataqueue if underlying database get corrupted
praveek Jul 25, 2023
ce0cbe2
Merge branch 'dev' of https://github.com/adobe/aepsdk-core-android in…
praveek Jul 25, 2023
9908f46
Fix return type for SQLDataQueue.clear()
praveek Jul 25, 2023
1d30a35
Fix comments
praveek Jul 26, 2023
0785f01
Update versions [Core-2.3.0] [Lifecycle-2.0.4]
praveek Jul 26, 2023
6011543
Merge pull request #514 from praveek/dev
praveek Jul 26, 2023
b030b8f
Merge pull request #515 from adobe/create-pull-request/patch
praveek Jul 26, 2023
b527dcb
Merge pull request #516 from adobe/dev
praveek Jul 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ public abstract interface class com/adobe/marketing/mobile/services/DeviceInform
public abstract fun getOperatingSystemVersion ()Ljava/lang/String;
public abstract fun getPropertyFromManifest (Ljava/lang/String;)Ljava/lang/String;
public abstract fun getRunMode ()Ljava/lang/String;
public abstract fun getSystemLocale ()Ljava/util/Locale;
public abstract fun registerOneTimeNetworkConnectionActiveListener (Lcom/adobe/marketing/mobile/services/DeviceInforming$NetworkConnectionActiveListener;)Z
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class DeviceInfoServiceTests {
ServiceProviderModifier.setAppContextService(MockAppContextService())
deviceInfoService = ServiceProvider.getInstance().deviceInfoService
assertNull(deviceInfoService.activeLocale)
assertTrue(deviceInfoService.systemLocale.displayLanguage.isNotEmpty())
assertNull(deviceInfoService.displayInformation)
assertEquals(
DeviceInforming.DeviceType.UNKNOWN,
Expand Down Expand Up @@ -73,6 +74,11 @@ class DeviceInfoServiceTests {
assertTrue(deviceInfoService.activeLocale.displayLanguage.isNotEmpty())
}

@Test
fun testGetSystemLocale() {
assertTrue(deviceInfoService.systemLocale.displayLanguage.isNotEmpty())
}

@Test
fun testGetCurrentOrientation() {
assertTrue(deviceInfoService.currentOrientation >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
package com.adobe.marketing.mobile.services;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import org.junit.After;
import org.junit.Assert;
Expand All @@ -25,19 +27,19 @@
@RunWith(AndroidJUnit4.class)
public class SqliteDataQueueTests {

private File dbFile;
private DataQueue dataQueue;
private static final String QUEUE_NAME = "test.dataQueue";

@Before
public void setUp() {
Context context = ApplicationProvider.getApplicationContext();
dbFile = context.getDatabasePath(QUEUE_NAME);
dataQueue = new SQLiteDataQueue(context.getDatabasePath(QUEUE_NAME).getPath());
}

@After
public void tearDown() {
Context context = ApplicationProvider.getApplicationContext();
File dbFile = getDatabase();
if (dbFile != null && dbFile.exists()) {
dbFile.delete();
}
Expand Down Expand Up @@ -98,4 +100,84 @@ public void testClear() {
List<DataEntity> results = dataQueue.peek(4);
Assert.assertEquals(0, results.size());
}

@Test
public void testAddToCorruptedDatabase() {
dataQueue.add(new DataEntity("test_data_1"));
dataQueue.add(new DataEntity("test_data_2"));
Assert.assertEquals(2, dataQueue.count());

corruptDatabase();
Assert.assertTrue(isDatabaseCorrupt());

// After detecting db is corrupt, resets the database and then adds the new entry.
Assert.assertTrue(dataQueue.add(new DataEntity("test_data_3")));
Assert.assertEquals(1, dataQueue.count());
Assert.assertEquals("test_data_3", dataQueue.peek().getData());
Assert.assertFalse(isDatabaseCorrupt());
}

@Test
public void testRemoveFromCorruptedDatabase() {
dataQueue.add(new DataEntity("test_data_1"));
dataQueue.add(new DataEntity("test_data_2"));
Assert.assertEquals(2, dataQueue.count());

corruptDatabase();
Assert.assertTrue(isDatabaseCorrupt());

// After detecting db is corrupt, resets the database.
Assert.assertFalse(dataQueue.remove());
Assert.assertEquals(0, dataQueue.count());
Assert.assertFalse(isDatabaseCorrupt());
}

@Test
public void testClearCorruptedDatabase() {
dataQueue.add(new DataEntity("test_data_1"));
dataQueue.add(new DataEntity("test_data_2"));
Assert.assertEquals(2, dataQueue.count());

corruptDatabase();
Assert.assertTrue(isDatabaseCorrupt());

// After detecting db is corrupt, resets the database.
Assert.assertTrue(dataQueue.clear());
Assert.assertEquals(0, dataQueue.count());
Assert.assertFalse(isDatabaseCorrupt());
}

private File getDatabase() {
Context context = ApplicationProvider.getApplicationContext();
return context.getDatabasePath(QUEUE_NAME);
}

private void corruptDatabase() {
File dbFile = getDatabase();
if (dbFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(getDatabase());
fos.write(new byte[1024]);
fos.close();
} catch (Exception e) {

}
}

private boolean isDatabaseCorrupt() {
File dbFile = getDatabase();
if (dbFile == null) {
return true;
}
try {
SQLiteDatabase database =
SQLiteDatabase.openDatabase(
dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
return database == null || !database.isDatabaseIntegrityOk();
} catch (Exception e) {
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ package com.adobe.marketing.mobile.internal

internal object CoreConstants {
const val LOG_TAG = "MobileCore"
const val VERSION = "2.2.3"
const val VERSION = "2.3.0"

object EventDataKeys {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ internal class AppIdManager {
* @return the existing appId stored in shared preferences if it exists,
* null otherwise.
*/
private fun getAppIDFromPersistence(): String? {
internal fun getAppIDFromPersistence(): String? {
return configStateStoreCollection?.getString(
ConfigurationStateManager.PERSISTED_APPID,
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,14 @@
return
}

// Check if this is an internal request ovewriting explicit configure with appId request.
val isInternalEvent = DataReader.optBoolean(event.eventData, CONFIGURATION_REQUEST_CONTENT_IS_INTERNAL_EVENT, false)
if (isStaleAppIdUpdateRequest(appId, isInternalEvent)) {
Log.trace(TAG, TAG, "An explicit configure with AppId request has preceded this internal event.")

Check warning on line 255 in code/core/src/main/java/com/adobe/marketing/mobile/internal/configuration/ConfigurationExtension.kt

View check run for this annotation

Codecov / codecov/patch

code/core/src/main/java/com/adobe/marketing/mobile/internal/configuration/ConfigurationExtension.kt#L255

Added line #L255 was not covered by tests
sharedStateResolver?.resolve(configurationStateManager.environmentAwareConfiguration)
return

Check warning on line 257 in code/core/src/main/java/com/adobe/marketing/mobile/internal/configuration/ConfigurationExtension.kt

View check run for this annotation

Codecov / codecov/patch

code/core/src/main/java/com/adobe/marketing/mobile/internal/configuration/ConfigurationExtension.kt#L257

Added line #L257 was not covered by tests
}

// Stop all event processing for the extension until new configuration download is attempted
api.stopEvents()

Expand Down Expand Up @@ -540,4 +548,24 @@
}
}
}

/**
* Determines if the current AppID update request is stale.
* A request is considered stale if it is a configuration request sent internally
* and there is a newer request that has been sent externally via {@link MobileCore#configureWithAppId(String)}
*
* @param newAppId the new app ID with which the configuration update is being requested
* @param isInternalEvent whether the current request is an initial configuration request
* @return true if the current request is stale, false otherwise
*/
private fun isStaleAppIdUpdateRequest(newAppId: String, isInternalEvent: Boolean): Boolean {
// Because events are dispatched and processed serially, external config with app id events
// cannot be stale.
if (!isInternalEvent) return false

// Load the currently persisted app id for validation
val persistedAppId = appIdManager.getAppIDFromPersistence()

return !persistedAppId.isNullOrBlank() && newAppId != persistedAppId
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,20 @@ interface DisplayInformation {
String getApplicationVersionCode();

/**
* Returns the currently selected / active locale value (as set by the user on the system).
* Returns the currently selected / active locale value with respect to the application context.
*
* @return A {@link Locale} value, if available, null otherwise
*/
Locale getActiveLocale();

/**
* Returns the currently selected / active locale value on the device settings as set by the
* user.
*
* @return A {@link Locale} value, if available, null otherwise
*/
Locale getSystemLocale();

/**
* Returns information about the display hardware, as returned by the underlying OS.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ class DeviceInfoService implements DeviceInforming {
DeviceInfoService() {}

/**
* Returns the currently selected / active locale value (as set by the user on the system).
* Returns the currently selected / active locale value with respect to the application context.
*
* @return A {@link Locale} value, if available, null otherwise.
* @return A {@link Locale} value, if available, null otherwise
*/
public Locale getActiveLocale() {
final Context context = getApplicationContext();
Expand All @@ -56,23 +56,18 @@ public Locale getActiveLocale() {
return null;
}

final Resources resources = context.getResources();

if (resources == null) {
return null;
}

final Configuration configuration = resources.getConfiguration();

if (configuration == null) {
return null;
}
return getLocaleFromResources(context.getResources());
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return configuration.locale;
} else {
return configuration.getLocales().get(0);
}
/**
* Returns the currently selected / active locale value on the device settings as set by the
* user.
*
* @return A {@link Locale} value, if available, null otherwise
*/
@Override
public Locale getSystemLocale() {
return getLocaleFromResources(Resources.getSystem());
}

@Override
Expand Down Expand Up @@ -581,6 +576,29 @@ public String getLocaleString() {
return result;
}

/**
* Returns the preferred locale value from the Resources object.
*
* @return A {@link Locale} value, if available, null otherwise
*/
private Locale getLocaleFromResources(final Resources resources) {
if (resources == null) {
return null;
}

final Configuration configuration = resources.getConfiguration();

if (configuration == null) {
return null;
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return configuration.locale;
} else {
return configuration.getLocales().get(0);
}
}

/**
* Checks if a {@code String} is null, empty or it only contains whitespaces.
*
Expand Down
Loading
Loading