Skip to content

Commit

Permalink
feat: sideloading kits (#401)
Browse files Browse the repository at this point in the history
* feat: sideloading kits (#378)

* Adding local kit as a wrapper for config and kit integration.
Creating empty config based on a random unused Int generated by the factory.
Adding kit merging and initializing.

* Changes on tests for compatibility

* Changes due to comments
Adding unit test to check getting config from KitIntegration wrapper set in MParticleOptions, KitManagerFactory creating instances, applying config, etc.

* Redoing sideloaded kits

* Changes into dependencies

* Combining sideloaded kits into prefs for merge.

* Adding capabilities for integration and merging sideloaded kits with remote config.

* Fixing unit tests

* # Conflicts:
#	android-core/src/main/java/com/mparticle/internal/ConfigManager.java

* ktlintFormat

* Test fixes

* Fixing incorrect HTML tag

* Changes due to comments

* Change due to comments

* Modification of long proguard

* ktlintFormat

* Changes due to team discussion.
Using kit instance and combine it with created instances.
Support for multiple instances.
Adding condition to filter sideloaded kits with id < 1000000

* Implementing default functions from KitIntegration

* Test fix

---------

Signed-off-by: markvdouw <v-mvanderouw@mparticle.com>
  • Loading branch information
markvdouw authored Jul 20, 2023
1 parent 2281194 commit 80de8ea
Show file tree
Hide file tree
Showing 28 changed files with 897 additions and 177 deletions.
2 changes: 2 additions & 0 deletions android-core/proguard.pro
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
-keep class com.mparticle.consent.CCPAConsent$Builder {*;}


-keep class com.mparticle.internal.SideloadedKit { *; }

-keep class com.mparticle.internal.KitManager { *; }
-keep class com.mparticle.internal.KitManager$* { *; }
-keep class com.mparticle.internal.CoreCallbacks { *; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package com.mparticle.internal
import com.mparticle.MParticle
import com.mparticle.MParticleOptions
import com.mparticle.testutils.BaseCleanInstallEachTest
import org.json.JSONArray
import org.json.JSONObject
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
import kotlin.test.assertTrue

class ConfigMigrationTest : BaseCleanInstallEachTest() {
private val oldConfigSharedprefsKey = "json"
Expand Down Expand Up @@ -81,7 +83,7 @@ class ConfigMigrationTest : BaseCleanInstallEachTest() {

// make sure config is deleted
MParticle.getInstance()!!.Internal().configManager.let {
assertNull(it.config)
assertTrue(it.config?.isEmpty()!!)
assertNull(it.configTimestamp)
assertNull(it.etag)
assertNull(it.ifModified)
Expand Down Expand Up @@ -127,13 +129,12 @@ class ConfigMigrationTest : BaseCleanInstallEachTest() {
}

private fun assertOldConfigState(config: JSONObject) {
assertNull(ConfigManager.getInstance(mContext).getKitConfigPreferences().getString(ConfigManager.KIT_CONFIG_KEY, null))
assertEquals(config.toString(), ConfigManager.getPreferences(mContext).getString(oldConfigSharedprefsKey, null))
assertEquals(config.toString(), ConfigManager.getPreferences(mContext).getString(oldConfigSharedprefsKey, JSONArray().toString()))
}

private fun assertNewConfigState(config: JSONObject) {
val configString = ConfigManager.getPreferences(mContext).getString(ConfigManager.CONFIG_JSON, null)
val configString = ConfigManager.getPreferences(mContext).getString(ConfigManager.CONFIG_JSON, JSONArray().toString())
assertNull(JSONObject(configString).optJSONArray(ConfigManager.KEY_EMBEDDED_KITS))
assertEquals(config.optString(ConfigManager.KEY_EMBEDDED_KITS, null), ConfigManager.getInstance(mContext).kitConfigPreferences.getString(ConfigManager.KIT_CONFIG_KEY, null))
assertEquals(config.optString(ConfigManager.KEY_EMBEDDED_KITS, JSONArray().toString()), ConfigManager.getInstance(mContext).kitConfigPreferences.getString(ConfigManager.KIT_CONFIG_KEY, JSONArray().toString()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue

class ConfigStalenessCheckTest : BaseCleanInstallEachTest() {
val configManager: ConfigManager
Expand Down Expand Up @@ -82,7 +83,7 @@ class ConfigStalenessCheckTest : BaseCleanInstallEachTest() {
latch = MPLatch(1)

// after configMaxAge time has elapsed, config should be cleared after restart
assertNull(configManager.config)
assertTrue(configManager.config?.isEmpty()!!)
assertNull(configManager.etag)
assertNull(configManager.ifModified)
assertNull(configManager.configTimestamp)
Expand Down Expand Up @@ -161,7 +162,7 @@ class ConfigStalenessCheckTest : BaseCleanInstallEachTest() {
latch = MPLatch(1)

// directly after restart, config should be cleared
assertNull(configManager.config)
assertTrue(configManager.config?.isEmpty()!!)
assertNull(configManager.etag)
assertNull(configManager.ifModified)
assertNull(configManager.configTimestamp)
Expand Down
6 changes: 4 additions & 2 deletions android-core/src/main/java/com/mparticle/MParticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private MParticle(MParticleOptions options) {
*/
public void setUpdateInterval(int interval) {
long intervalMillis = interval * 1000L;
if ( (intervalMillis >= 1 && mConfigManager.getUploadInterval() != intervalMillis)) {
if ((intervalMillis >= 1 && mConfigManager.getUploadInterval() != intervalMillis)) {
upload();
mConfigManager.setUploadInterval(interval);
}
Expand Down Expand Up @@ -293,6 +293,7 @@ public static boolean isAndroidIdEnabled() {

/**
* Returns the wrapper sdk version
*
* @return
*/
public WrapperSdkVersion getWrapperSdkVersion() {
Expand All @@ -302,6 +303,7 @@ public WrapperSdkVersion getWrapperSdkVersion() {
/**
* Set wrapper sdk, by default NONE.
* This can only be set once.
*
* @param wrapperSdk diffent from {@link WrapperSdk.NONE}
* @param version
*/
Expand Down Expand Up @@ -1508,7 +1510,7 @@ public void onUserIdentified(MParticleUser user, MParticleUser previousUser) {
if (user != null) {
Identity().removeIdentityStateListener(this);
Logger.verbose("Sending previously deferred logPushRegistration Modify request.");
sendPushTokenModifyRequest(user, newInstanceId, oldInstanceId);
sendPushTokenModifyRequest(user, newInstanceId, oldInstanceId);
}
}
};
Expand Down
35 changes: 34 additions & 1 deletion android-core/src/main/java/com/mparticle/MParticleOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
import com.mparticle.internal.Logger;
import com.mparticle.internal.MPUtility;
import com.mparticle.internal.PushRegistrationHelper;
import com.mparticle.internal.SideloadedKit;
import com.mparticle.networking.NetworkOptions;
import com.mparticle.networking.NetworkOptionsManager;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;

Expand Down Expand Up @@ -54,6 +54,7 @@ public class MParticleOptions {
private MParticle.OperatingSystem mOperatingSystem = MParticle.OperatingSystem.ANDROID;
private DataplanOptions mDataplanOptions;
private Map<Class, List<Configuration>> mConfigurations = new HashMap();
private List<SideloadedKit> sideloadedKits = new ArrayList<>();

private MParticleOptions() {
}
Expand Down Expand Up @@ -145,6 +146,7 @@ public MParticleOptions(@NonNull Builder builder) {
this.mDataplanVersion = builder.dataplanVersion;
this.mDataplanOptions = builder.dataplanOptions;
this.mConfigurations = builder.configurations;
this.sideloadedKits = builder.sideloadedKits;
}

/**
Expand Down Expand Up @@ -179,6 +181,16 @@ public MParticle.Environment getEnvironment() {
return mEnvironment;
}

/**
* Get list of sideloadedKits kits
*
* @return
*/
@NonNull
public List<SideloadedKit> getSideloadedKits() {
return sideloadedKits;
}

/**
* Query the API Key.
*
Expand Down Expand Up @@ -387,6 +399,7 @@ public static class Builder {
private DataplanOptions dataplanOptions;
private Map<Class, List<Configuration>> configurations = new HashMap();
private boolean isAppDebuggable;
private List<SideloadedKit> sideloadedKits = new ArrayList<>();

private Builder(Context context) {
this.context = context;
Expand Down Expand Up @@ -421,6 +434,26 @@ public Builder installType(@NonNull MParticle.InstallType installType) {
return this;
}

/**
* Add sideloaded kits
*
* @param kits
* @return
*/
@NonNull
public Builder sideloadedKits(@NonNull List<SideloadedKit> kits) {
List<SideloadedKit> _kits = new ArrayList<>();
for (SideloadedKit kit : kits) {
if (kit.kitId() < 1000000) {
Logger.error("Sideloaded kit " + kit.getName() + " must have a kitId greater or equal than 1000000, current one is " + kit.kitId() + " and will not be included.");
} else {
_kits.add(kit);
}
}
this.sideloadedKits = _kits;
return this;
}

/**
* Indicate a known {@link com.mparticle.MParticle.Environment} the Application will be running in. If this method is not used.
* a default Environment of MParticle.Environment.AutoDetect will be used.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class ConfigManager {
static final String DATAPLAN_BLOCK_EVENT_ATTRIBUTES = "ea";
static final String DATAPLAN_BLOCK_USER_ATTRIBUTES = "ua";
static final String DATAPLAN_BLOCK_USER_IDENTITIES = "id";
static final String KIT_CONFIG_KEY = "kit_config";
public static final String KIT_CONFIG_KEY = "kit_config";
static final String MIGRATED_TO_KIT_SHARED_PREFS = "is_mig_kit_sp";

private static final int DEVMODE_UPLOAD_INTERVAL_MILLISECONDS = 10 * 1000;
Expand Down Expand Up @@ -106,6 +106,7 @@ public class ConfigManager {
public static final int DEFAULT_SESSION_TIMEOUT_SECONDS = 60;
public static final int DEFAULT_UPLOAD_INTERVAL = 600;
private List<ConfigLoadedListener> configUpdatedListeners = new ArrayList<>();
private List<SideloadedKit> sideloadedKits = new ArrayList<>();

private ConfigManager() {
super();
Expand All @@ -129,10 +130,10 @@ public ConfigManager(Context context) {
}

public ConfigManager(@NonNull MParticleOptions options) {
this(options.getContext(), options.getEnvironment(), options.getApiKey(), options.getApiSecret(), options.getDataplanOptions(), options.getDataplanId(), options.getDataplanVersion(), options.getConfigMaxAge(), options.getConfigurationsForTarget(ConfigManager.class));
this(options.getContext(), options.getEnvironment(), options.getApiKey(), options.getApiSecret(), options.getDataplanOptions(), options.getDataplanId(), options.getDataplanVersion(), options.getConfigMaxAge(), options.getConfigurationsForTarget(ConfigManager.class), options.getSideloadedKits());
}

public ConfigManager(@NonNull Context context, @Nullable MParticle.Environment environment, @Nullable String apiKey, @Nullable String apiSecret, @Nullable MParticleOptions.DataplanOptions dataplanOptions, @Nullable String dataplanId, @Nullable Integer dataplanVersion, @Nullable Integer configMaxAge, @Nullable List<Configuration<ConfigManager>> configurations) {
public ConfigManager(@NonNull Context context, @Nullable MParticle.Environment environment, @Nullable String apiKey, @Nullable String apiSecret, @Nullable MParticleOptions.DataplanOptions dataplanOptions, @Nullable String dataplanId, @Nullable Integer dataplanVersion, @Nullable Integer configMaxAge, @Nullable List<Configuration<ConfigManager>> configurations, @Nullable List<SideloadedKit> sideloadedKits) {
mContext = context.getApplicationContext();
sPreferences = getPreferences(mContext);
if (apiKey != null || apiSecret != null) {
Expand All @@ -148,6 +149,11 @@ public ConfigManager(@NonNull Context context, @Nullable MParticle.Environment e
mDataplanVersion = dataplanVersion;
mDataplanId = dataplanId;
mMaxConfigAge = configMaxAge;
if (sideloadedKits != null) {
this.sideloadedKits = sideloadedKits;
} else {
this.sideloadedKits = new ArrayList<>();
}
if (configurations != null) {
for (Configuration configuration : configurations) {
configuration.apply(this);
Expand Down Expand Up @@ -277,7 +283,7 @@ void checkConfigStaleness() {

@Nullable
String getConfig() {
return sPreferences.getString(CONFIG_JSON, null);
return sPreferences.getString(CONFIG_JSON, "");
}

void setConfigTimestamp(Long timestamp) {
Expand Down Expand Up @@ -321,7 +327,7 @@ void saveConfigJson(JSONObject coreConfig, JSONArray kitConfig, String etag, Str
.apply();
getKitConfigPreferences()
.edit()
.putString(KIT_CONFIG_KEY, kitConfigString)
.putString(KIT_CONFIG_KEY, SideloadedKitsUtils.INSTANCE.combineConfig(kitConfig, sideloadedKits).toString())
.apply();
} else {
Logger.debug("clearing current configurations");
Expand All @@ -346,7 +352,26 @@ public synchronized void updateConfig(JSONObject responseJSON) throws JSONExcept
updateConfig(responseJSON, null, null);
}

public synchronized void updateConfig(JSONObject responseJSON, String etag, String lastModified) throws JSONException {
public synchronized void configUpToDate() throws JSONException {
try {
String config = getKitConfigPreferences().getString(KIT_CONFIG_KEY, "");
if (!config.isEmpty()) {
JSONArray kitConfig = new JSONArray(config);
JSONArray combined = SideloadedKitsUtils.INSTANCE.combineConfig(kitConfig, sideloadedKits);
getKitConfigPreferences()
.edit()
.putString(KIT_CONFIG_KEY, combined.toString())
.apply();
onConfigLoaded(ConfigType.KIT, kitConfig != combined);
}
} catch (JSONException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

public synchronized void updateConfig(JSONObject responseJSON, String etag, String
lastModified) throws JSONException {
if (responseJSON == null) {
responseJSON = new JSONObject();
}
Expand All @@ -369,7 +394,8 @@ private synchronized void updateKitConfig(@Nullable JSONArray kitConfigs) {
}
}

private synchronized void updateCoreConfig(JSONObject responseJSON, boolean newConfig) throws JSONException {
private synchronized void updateCoreConfig(JSONObject responseJSON, boolean newConfig) throws
JSONException {
SharedPreferences.Editor editor = sPreferences.edit();
if (responseJSON.has(KEY_UNHANDLED_EXCEPTIONS)) {
mLogUnhandledExceptions = responseJSON.getString(KEY_UNHANDLED_EXCEPTIONS);
Expand Down Expand Up @@ -673,7 +699,8 @@ public void setPushRegistration(PushRegistrationHelper.PushRegistration pushRegi
}
}

public void setPushRegistrationInBackground(PushRegistrationHelper.PushRegistration pushRegistration) {
public void setPushRegistrationInBackground(PushRegistrationHelper.PushRegistration
pushRegistration) {
String oldInstanceId = getPushInstanceId();
if (oldInstanceId == null) {
oldInstanceId = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ public interface MessageKey {
String LAUNCH_COUNT = "lc";
String LAUNCH_COUNT_SINCE_UPGRADE = "lcu";
String LAST_USE_DATE = "lud";
String SIDELOADED_KITS_COUNT = "sideloaded_kits_count";
// device customAttributes
String BUILD_ID = "bid";
String BRAND = "b";
Expand Down
Loading

0 comments on commit 80de8ea

Please sign in to comment.