From 7c66d3c934cb0928d20a9721099dcfcf5f0508a2 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Fri, 17 Nov 2023 13:29:56 -0300 Subject: [PATCH 1/5] Checking if we should make an identiy call or return saved MParticleUser based on last request (using timeout) and several conditions. --- .../com/mparticle/identity/IdentityApi.java | 54 +++++++++++++++++-- .../identity/MParticleIdentityClientImpl.java | 1 + 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java index b7348845f..4178ee613 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java @@ -1,5 +1,7 @@ package com.mparticle.identity; +import static com.mparticle.identity.MParticleIdentityClientImpl.IDENTITY_TIMEOUT; + import android.annotation.SuppressLint; import android.content.Context; import android.os.Handler; @@ -24,8 +26,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -175,7 +179,7 @@ public IdentityHttpResponse request(IdentityApiRequest request) throws Exception public void onPostExecute(IdentityApiResult result) { mKitManager.onLogoutCompleted(result.getUser(), logoutRequest); } - }); + }, false); } /** @@ -210,7 +214,7 @@ public IdentityHttpResponse request(IdentityApiRequest request) throws Exception public void onPostExecute(IdentityApiResult result) { mKitManager.onLoginCompleted(result.getUser(), loginRequest); } - }); + }, true); } /** @@ -233,7 +237,7 @@ public IdentityHttpResponse request(IdentityApiRequest request) throws Exception public void onPostExecute(IdentityApiResult result) { mKitManager.onIdentifyCompleted(result.getUser(), identifyRequest); } - }); + }, true); } /** @@ -348,13 +352,52 @@ private void reset() { } } - private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final IdentityNetworkRequestRunnable networkRequest) { + private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse) { + if (!acceptCachedResponse) { + return true; + } + long lastIdentityCall = 0l;// TODO get from prefs + boolean hasTimedOut = lastIdentityCall < System.currentTimeMillis() - IDENTITY_TIMEOUT; //TODO Check if the timeout should be dynamic based on server header + MParticleUser user = getUser(identityRequest.mpid); + if (hasTimedOut || isRequestDifferent(user, identityRequest)) { + return true; + } else { + return false; + } + } + + private boolean isRequestDifferent(MParticleUser user, IdentityApiRequest identityRequest) { + return areIdentitiesDifferent(user, identityRequest) || mpIdNotKnown(user); + } + + private boolean mpIdNotKnown(MParticleUser user) { + return user != null && !mConfigManager.getMpids().contains(user.getId()); + } + + private boolean areIdentitiesDifferent(MParticleUser user, IdentityApiRequest identityApiRequest) { + //TODO params such as device id, android id, and google id should be persisted in user or userIdentity to be compared. + if (user != null) { + Map userIdentities = user.getUserIdentities() != null ? user.getUserIdentities() : new HashMap<>(); + Map requestUserIdentities = identityApiRequest.getUserIdentities() != null ? identityApiRequest.getUserIdentities() : new HashMap<>(); + return !userIdentities.equals(requestUserIdentities); + } else { + return true; + } + } + + private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final IdentityNetworkRequestRunnable networkRequest, boolean acceptCachedResponse) { if (request == null) { request = IdentityApiRequest.withEmptyUser().build(); } final BaseIdentityTask task = new BaseIdentityTask(); - ConfigManager.setIdentityRequestInProgress(true); final IdentityApiRequest identityApiRequest = request; + if (!shouldMakeRequest(identityApiRequest, acceptCachedResponse)) { + //Set both current and prev user as the current one, no request was done. + task.setSuccessful(new IdentityApiResult(getUser(identityApiRequest.mpid), getCurrentUser())); + Logger.debug("Identity -Returning current user from cache"); + return task; + } + ConfigManager.setIdentityRequestInProgress(true); mBackgroundHandler.post(new Runnable() { @Override public void run() { @@ -362,6 +405,7 @@ public void run() { if (mBackgroundHandler.isDisabled()) { return; } + Logger.debug("Identity - Making identity call for request"); try { long startingMpid = mConfigManager.getMpid(); final IdentityHttpResponse result = networkRequest.request(identityApiRequest); diff --git a/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java b/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java index 06117fe7f..ba47c5135 100644 --- a/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java +++ b/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java @@ -31,6 +31,7 @@ public class MParticleIdentityClientImpl extends MParticleBaseClientImpl impleme private Context mContext; private ConfigManager mConfigManager; + static final long IDENTITY_TIMEOUT = 24 * 60 * 60 * 1000L; static final String LOGIN_PATH = "login"; static final String LOGOUT_PATH = "logout"; static final String IDENTIFY_PATH = "identify"; From 535ef8730123971e23af7e45e73e3d2f501f7393 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Fri, 5 Jan 2024 13:04:30 -0300 Subject: [PATCH 2/5] Changes for identity cache --- .../com/mparticle/identity/IdentityApi.java | 64 ++++++++++++++----- .../identity/IdentityHttpResponse.java | 8 ++- .../identity/MParticleIdentityClientImpl.java | 21 ++++-- .../com/mparticle/internal/ConfigManager.java | 16 +++++ 4 files changed, 86 insertions(+), 23 deletions(-) diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java index 4178ee613..29ba9c302 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java @@ -1,7 +1,5 @@ package com.mparticle.identity; -import static com.mparticle.identity.MParticleIdentityClientImpl.IDENTITY_TIMEOUT; - import android.annotation.SuppressLint; import android.content.Context; import android.os.Handler; @@ -50,6 +48,7 @@ public class IdentityApi { MessageManager mMessageManager; KitManager mKitManager; private Internal mInternal = new Internal(); + private long timeoutSeconds = 0L; MParticleUserDelegate mUserDelegate; private MParticleIdentityClient mApiClient; @@ -57,6 +56,10 @@ public class IdentityApi { Set identityStateListeners = new HashSet(); private static Object lock = new Object(); + public static final String LOGIN_CALL = "login"; + public static final String IDENTIFY_CALL = "identify"; + public static final String LOGOUT_CALL = "logout"; + protected IdentityApi() { } @@ -169,6 +172,7 @@ public MParticleTask logout() { */ @NonNull public MParticleTask logout(@Nullable final IdentityApiRequest logoutRequest) { + resetCache(); return makeIdentityRequest(logoutRequest, new IdentityNetworkRequestRunnable() { @Override public IdentityHttpResponse request(IdentityApiRequest request) throws Exception { @@ -179,7 +183,7 @@ public IdentityHttpResponse request(IdentityApiRequest request) throws Exception public void onPostExecute(IdentityApiResult result) { mKitManager.onLogoutCompleted(result.getUser(), logoutRequest); } - }, false); + }, false, LOGOUT_CALL); } /** @@ -207,14 +211,17 @@ public MParticleTask login(@Nullable final IdentityApiRequest return makeIdentityRequest(loginRequest, new IdentityNetworkRequestRunnable() { @Override public IdentityHttpResponse request(IdentityApiRequest request) throws Exception { - return getApiClient().login(request); + IdentityHttpResponse response = getApiClient().login(request); + timeoutSeconds = response.getTimeout(); + Logger.debug("TIMEOUT - IDENTITY TIMEOUT SET (SEC): "+ timeoutSeconds); + return response; } @Override public void onPostExecute(IdentityApiResult result) { mKitManager.onLoginCompleted(result.getUser(), loginRequest); } - }, true); + }, true, LOGIN_CALL); } /** @@ -230,14 +237,17 @@ public MParticleTask identify(@Nullable final IdentityApiRequ return makeIdentityRequest(identifyRequest, new IdentityNetworkRequestRunnable() { @Override public IdentityHttpResponse request(IdentityApiRequest request) throws Exception { - return getApiClient().identify(request); + IdentityHttpResponse response = getApiClient().identify(request); + timeoutSeconds = response.getTimeout(); + Logger.debug("TIMEOUT - IDENTITY TIMEOUT SET (SEC): "+ timeoutSeconds); + return response; } @Override public void onPostExecute(IdentityApiResult result) { mKitManager.onIdentifyCompleted(result.getUser(), identifyRequest); } - }, true); + }, true, IDENTIFY_CALL); } /** @@ -256,6 +266,7 @@ public BaseIdentityTask modify(@NonNull final IdentityApiRequest updateRequest) if (updateRequest.mpid == null) { updateRequest.mpid = mConfigManager.getMpid(); } + if (Constants.TEMPORARY_MPID.equals(updateRequest.mpid)) { String message = "modify() requires a non-zero MPID, please make sure a MParticleUser is present before making a modify request."; if (devMode) { @@ -270,10 +281,12 @@ public BaseIdentityTask modify(@NonNull final IdentityApiRequest updateRequest) @Override public void run() { try { + resetCache(); final IdentityHttpResponse result = getApiClient().modify(updateRequest); if (!result.isSuccessful()) { task.setFailed(result); } else { + timeoutSeconds = result.getTimeout(); MParticleUserDelegate.setUserIdentities(mUserDelegate, updateRequest.getUserIdentities(), updateRequest.mpid); task.setSuccessful(new IdentityApiResult(MParticleUserImpl.getInstance(mContext, updateRequest.mpid, mUserDelegate), null)); new Handler(Looper.getMainLooper()).post(new Runnable() { @@ -352,17 +365,25 @@ private void reset() { } } - private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse) { + private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse, long lastIdentityCall) { if (!acceptCachedResponse) { + Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE"); return true; } - long lastIdentityCall = 0l;// TODO get from prefs - boolean hasTimedOut = lastIdentityCall < System.currentTimeMillis() - IDENTITY_TIMEOUT; //TODO Check if the timeout should be dynamic based on server header - MParticleUser user = getUser(identityRequest.mpid); - if (hasTimedOut || isRequestDifferent(user, identityRequest)) { - return true; + boolean hasTimedOut = lastIdentityCall==-1L || (lastIdentityCall + (timeoutSeconds * 1000) > System.currentTimeMillis()) ; + Logger.debug("TIMEOUT - REQUEST TIMED OUT: " + hasTimedOut); + if (identityRequest != null && identityRequest.mpid != null) { + MParticleUser user = getUser(identityRequest.mpid); + if (hasTimedOut || isRequestDifferent(user, identityRequest)) { + Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE"); + return true; + } else { + Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: FALSE"); + return false; + } } else { - return false; + Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE"); + return true; } } @@ -379,19 +400,27 @@ private boolean areIdentitiesDifferent(MParticleUser user, IdentityApiRequest id if (user != null) { Map userIdentities = user.getUserIdentities() != null ? user.getUserIdentities() : new HashMap<>(); Map requestUserIdentities = identityApiRequest.getUserIdentities() != null ? identityApiRequest.getUserIdentities() : new HashMap<>(); + Logger.debug("TIMEOUT - USER IDENTITIES: " +userIdentities); + Logger.debug("TIMEOUT - REQUEST USER IDENTITIES: " +requestUserIdentities); + Logger.debug("TIMEOUT - RESULT DIFFERENT: " + !userIdentities.equals(requestUserIdentities)); return !userIdentities.equals(requestUserIdentities); } else { return true; } } - private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final IdentityNetworkRequestRunnable networkRequest, boolean acceptCachedResponse) { + private void resetCache() { + mConfigManager.resetIdentityTypeCall(); + } + + private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final IdentityNetworkRequestRunnable networkRequest, boolean acceptCachedResponse, String call) { + long lastIdentityCallTime = mConfigManager.getLastIdentityTypeCall(call); if (request == null) { request = IdentityApiRequest.withEmptyUser().build(); } final BaseIdentityTask task = new BaseIdentityTask(); final IdentityApiRequest identityApiRequest = request; - if (!shouldMakeRequest(identityApiRequest, acceptCachedResponse)) { + if (!shouldMakeRequest(identityApiRequest, acceptCachedResponse, lastIdentityCallTime)) { //Set both current and prev user as the current one, no request was done. task.setSuccessful(new IdentityApiResult(getUser(identityApiRequest.mpid), getCurrentUser())); Logger.debug("Identity -Returning current user from cache"); @@ -419,6 +448,9 @@ public void run() { ConfigManager.setIdentityRequestInProgress(false); mUserDelegate.setUser(mContext, startingMpid, newMpid, identityApiRequest.getUserIdentities(), identityApiRequest.getUserAliasHandler(), isLoggedIn); final MParticleUser previousUser = startingMpid != newMpid ? getUser(startingMpid) : null; + if (acceptCachedResponse) { + mConfigManager.setLastIdentityTypeCall(call); + } task.setSuccessful(new IdentityApiResult(MParticleUserImpl.getInstance(mContext, newMpid, mUserDelegate), previousUser)); new Handler(Looper.getMainLooper()).post(new Runnable() { @Override diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java b/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java index 00ca54d5a..627a0260b 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java @@ -18,6 +18,7 @@ public final class IdentityHttpResponse { private String context; private int httpCode; private boolean loggedIn; + private long timeout = 0L; @NonNull public static final String MPID = "mpid"; @@ -50,8 +51,9 @@ public IdentityHttpResponse(int code, @NonNull String errorString) { this.errors.add(new Error(UNKNOWN, errorString)); } - public IdentityHttpResponse(int httpCode, @Nullable JSONObject jsonObject) throws JSONException { + public IdentityHttpResponse(int httpCode, @Nullable JSONObject jsonObject, long identityTimeout) throws JSONException { this.httpCode = httpCode; + this.timeout = identityTimeout; if (!MPUtility.isEmpty(jsonObject)) { if (jsonObject.has(MPID)) { this.mpId = Long.valueOf(jsonObject.getString(MPID)); @@ -92,6 +94,10 @@ public long getMpId() { return mpId; } + public long getTimeout() { + return 30L; + } + @Nullable public String getContext() { return context; diff --git a/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java b/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java index ba47c5135..c1474859e 100644 --- a/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java +++ b/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java @@ -52,6 +52,7 @@ public class MParticleIdentityClientImpl extends MParticleBaseClientImpl impleme static final String DEVICE_APPLICATION_STAMP = "device_application_stamp"; static final String KNOWN_IDENTITIES = "known_identities"; static final String PREVIOUS_MPID = "previous_mpid"; + static final String IDENTITY_HEADER_TIMEOUT = "X-MP-Max-Age"; static final String NEW_VALUE = "new_value"; static final String OLD_VALUE = "old_value"; @@ -81,10 +82,11 @@ public IdentityHttpResponse login(IdentityApiRequest request) throws JSONExcepti String url = connection.getURL().toString(); InternalListenerManager.getListener().onNetworkRequestStarted(SdkListener.Endpoint.IDENTITY_LOGIN, url, jsonObject, request); connection = makeUrlRequest(Endpoint.IDENTITY, connection, jsonObject.toString(), false); + String headerField = connection.getHeaderField(IDENTITY_HEADER_TIMEOUT); int responseCode = connection.getResponseCode(); JSONObject response = MPUtility.getJsonResponse(connection); InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_LOGIN, url, response, responseCode); - return parseIdentityResponse(responseCode, response); + return parseIdentityResponse(responseCode, response, headerField); } public IdentityHttpResponse logout(IdentityApiRequest request) throws JSONException, IOException { @@ -97,7 +99,7 @@ public IdentityHttpResponse logout(IdentityApiRequest request) throws JSONExcept int responseCode = connection.getResponseCode(); JSONObject response = MPUtility.getJsonResponse(connection); InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_LOGOUT, url, response, responseCode); - return parseIdentityResponse(responseCode, response); + return parseIdentityResponse(responseCode, response, "0"); } public IdentityHttpResponse identify(IdentityApiRequest request) throws JSONException, IOException { @@ -107,10 +109,11 @@ public IdentityHttpResponse identify(IdentityApiRequest request) throws JSONExce String url = connection.getURL().toString(); InternalListenerManager.getListener().onNetworkRequestStarted(SdkListener.Endpoint.IDENTITY_IDENTIFY, url, jsonObject, request); connection = makeUrlRequest(Endpoint.IDENTITY, connection, jsonObject.toString(), false); + String headerField = connection.getHeaderField(IDENTITY_HEADER_TIMEOUT); int responseCode = connection.getResponseCode(); JSONObject response = MPUtility.getJsonResponse(connection); InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_IDENTIFY, url, response, responseCode); - return parseIdentityResponse(responseCode, response); + return parseIdentityResponse(responseCode, response, headerField); } public IdentityHttpResponse modify(IdentityApiRequest request) throws JSONException, IOException { @@ -125,9 +128,10 @@ public IdentityHttpResponse modify(IdentityApiRequest request) throws JSONExcept InternalListenerManager.getListener().onNetworkRequestStarted(SdkListener.Endpoint.IDENTITY_MODIFY, url, jsonObject, request); connection = makeUrlRequest(Endpoint.IDENTITY, connection, jsonObject.toString(), false); int responseCode = connection.getResponseCode(); + String headerField = connection.getHeaderField(IDENTITY_HEADER_TIMEOUT); JSONObject response = MPUtility.getJsonResponse(connection); InternalListenerManager.getListener().onNetworkRequestFinished(SdkListener.Endpoint.IDENTITY_MODIFY, url, response, responseCode); - return parseIdentityResponse(responseCode, response); + return parseIdentityResponse(responseCode, response, headerField); } private JSONObject getBaseJson() throws JSONException { @@ -239,13 +243,18 @@ private JSONObject getChangeJson(IdentityApiRequest request) throws JSONExceptio return jsonObject; } - private IdentityHttpResponse parseIdentityResponse(int httpCode, JSONObject jsonObject) { + private IdentityHttpResponse parseIdentityResponse(int httpCode, JSONObject jsonObject, String identityTimeoutHeader) { + long timeoutHeader = 0L; try { Logger.verbose("Identity response code: " + httpCode); if (jsonObject != null) { Logger.verbose("Identity result: " + jsonObject.toString()); } - IdentityHttpResponse httpResponse = new IdentityHttpResponse(httpCode, jsonObject); + try { + timeoutHeader = Long.parseLong(identityTimeoutHeader); + } catch (Exception e) { + } + IdentityHttpResponse httpResponse = new IdentityHttpResponse(httpCode, jsonObject, timeoutHeader); if (!MPUtility.isEmpty(httpResponse.getContext())) { mConfigManager.setIdentityApiContext(httpResponse.getContext()); } diff --git a/android-core/src/main/java/com/mparticle/internal/ConfigManager.java b/android-core/src/main/java/com/mparticle/internal/ConfigManager.java index 01d4fb628..c0c8870db 100644 --- a/android-core/src/main/java/com/mparticle/internal/ConfigManager.java +++ b/android-core/src/main/java/com/mparticle/internal/ConfigManager.java @@ -1251,6 +1251,22 @@ public int getIdentityConnectionTimeout() { return sPreferences.getInt(Constants.PrefKeys.IDENTITY_CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT_SECONDS) * 1000; } + public long getLastIdentityTypeCall(String call) { + return sPreferences.getLong(call, 0L); + } + + public void resetIdentityTypeCall() { + SharedPreferences.Editor editor = sPreferences.edit(); + editor.putLong(IdentityApi.LOGIN_CALL, -1); + editor.putLong(IdentityApi.IDENTIFY_CALL, -1); + editor.apply(); + } + + public void setLastIdentityTypeCall(String call) { + Logger.debug("TIMEOUT - SET LAST IDENTITY TIME CALL FOR " + call + " : " + System.currentTimeMillis()); + sPreferences.edit().putLong(call, System.currentTimeMillis()).apply(); + } + public int getConnectionTimeout() { return DEFAULT_CONNECTION_TIMEOUT_SECONDS * 1000; } From 61605a8929153ea4bc56a69d395d8fad6c64da13 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Wed, 10 Jan 2024 08:23:47 -0300 Subject: [PATCH 3/5] Removing testing logs --- .../java/com/mparticle/identity/IdentityApi.java | 15 ++------------- .../mparticle/identity/IdentityHttpResponse.java | 2 +- .../identity/MParticleIdentityClientImpl.java | 1 - .../com/mparticle/internal/ConfigManager.java | 1 - 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java index 29ba9c302..938ee4538 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java @@ -213,7 +213,6 @@ public MParticleTask login(@Nullable final IdentityApiRequest public IdentityHttpResponse request(IdentityApiRequest request) throws Exception { IdentityHttpResponse response = getApiClient().login(request); timeoutSeconds = response.getTimeout(); - Logger.debug("TIMEOUT - IDENTITY TIMEOUT SET (SEC): "+ timeoutSeconds); return response; } @@ -239,7 +238,6 @@ public MParticleTask identify(@Nullable final IdentityApiRequ public IdentityHttpResponse request(IdentityApiRequest request) throws Exception { IdentityHttpResponse response = getApiClient().identify(request); timeoutSeconds = response.getTimeout(); - Logger.debug("TIMEOUT - IDENTITY TIMEOUT SET (SEC): "+ timeoutSeconds); return response; } @@ -367,22 +365,17 @@ private void reset() { private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse, long lastIdentityCall) { if (!acceptCachedResponse) { - Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE"); return true; } - boolean hasTimedOut = lastIdentityCall==-1L || (lastIdentityCall + (timeoutSeconds * 1000) > System.currentTimeMillis()) ; - Logger.debug("TIMEOUT - REQUEST TIMED OUT: " + hasTimedOut); + boolean hasTimedOut = lastIdentityCall == -1L || (lastIdentityCall + (timeoutSeconds * 1000) > System.currentTimeMillis()); if (identityRequest != null && identityRequest.mpid != null) { MParticleUser user = getUser(identityRequest.mpid); if (hasTimedOut || isRequestDifferent(user, identityRequest)) { - Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE"); return true; } else { - Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: FALSE"); return false; } } else { - Logger.debug("TIMEOUT - SHOULD MAKE REQUEST: TRUE"); return true; } } @@ -396,13 +389,9 @@ private boolean mpIdNotKnown(MParticleUser user) { } private boolean areIdentitiesDifferent(MParticleUser user, IdentityApiRequest identityApiRequest) { - //TODO params such as device id, android id, and google id should be persisted in user or userIdentity to be compared. if (user != null) { Map userIdentities = user.getUserIdentities() != null ? user.getUserIdentities() : new HashMap<>(); Map requestUserIdentities = identityApiRequest.getUserIdentities() != null ? identityApiRequest.getUserIdentities() : new HashMap<>(); - Logger.debug("TIMEOUT - USER IDENTITIES: " +userIdentities); - Logger.debug("TIMEOUT - REQUEST USER IDENTITIES: " +requestUserIdentities); - Logger.debug("TIMEOUT - RESULT DIFFERENT: " + !userIdentities.equals(requestUserIdentities)); return !userIdentities.equals(requestUserIdentities); } else { return true; @@ -423,7 +412,7 @@ private BaseIdentityTask makeIdentityRequest(IdentityApiRequest request, final I if (!shouldMakeRequest(identityApiRequest, acceptCachedResponse, lastIdentityCallTime)) { //Set both current and prev user as the current one, no request was done. task.setSuccessful(new IdentityApiResult(getUser(identityApiRequest.mpid), getCurrentUser())); - Logger.debug("Identity -Returning current user from cache"); + Logger.debug("Identity - Returning current user from cache"); return task; } ConfigManager.setIdentityRequestInProgress(true); diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java b/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java index 627a0260b..420faeb06 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityHttpResponse.java @@ -95,7 +95,7 @@ public long getMpId() { } public long getTimeout() { - return 30L; + return timeout; } @Nullable diff --git a/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java b/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java index c1474859e..78d14cfe5 100644 --- a/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java +++ b/android-core/src/main/java/com/mparticle/identity/MParticleIdentityClientImpl.java @@ -31,7 +31,6 @@ public class MParticleIdentityClientImpl extends MParticleBaseClientImpl impleme private Context mContext; private ConfigManager mConfigManager; - static final long IDENTITY_TIMEOUT = 24 * 60 * 60 * 1000L; static final String LOGIN_PATH = "login"; static final String LOGOUT_PATH = "logout"; static final String IDENTIFY_PATH = "identify"; diff --git a/android-core/src/main/java/com/mparticle/internal/ConfigManager.java b/android-core/src/main/java/com/mparticle/internal/ConfigManager.java index c0c8870db..6199b06e7 100644 --- a/android-core/src/main/java/com/mparticle/internal/ConfigManager.java +++ b/android-core/src/main/java/com/mparticle/internal/ConfigManager.java @@ -1263,7 +1263,6 @@ public void resetIdentityTypeCall() { } public void setLastIdentityTypeCall(String call) { - Logger.debug("TIMEOUT - SET LAST IDENTITY TIME CALL FOR " + call + " : " + System.currentTimeMillis()); sPreferences.edit().putLong(call, System.currentTimeMillis()).apply(); } From 1617f8b34332d3b15c80b90cccad2ef7f13669a6 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Wed, 17 Jan 2024 11:53:00 -0300 Subject: [PATCH 4/5] Fixing tests --- .../com.mparticle/identity/IdentityApiStartTest.kt | 12 +++--------- .../com/mparticle/testutils/BaseAbstractTest.java | 2 -- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt b/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt index 6117b4807..69707f5a9 100644 --- a/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt +++ b/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt @@ -63,18 +63,12 @@ class IdentityApiStartTest : BaseCleanInstallEachTest() { @Test @Throws(Exception::class) fun testNoInitialIdentity() { - val currentMpid = ran.nextLong() - val identities = mRandomUtils.randomUserIdentities startMParticle() - MParticle.getInstance()?.Internal()?.configManager?.setMpid(currentMpid, ran.nextBoolean()) - for ((key, value) in identities) { - AccessUtils.setUserIdentity(value, key, currentMpid) - } - com.mparticle.internal.AccessUtils.awaitMessageHandler() + TestCase.assertEquals(mServer.Requests().identify.size, 1) mServer = MockServer.getNewInstance(mContext) startMParticle() - TestCase.assertEquals(mServer.Requests().identify.size, 1) - assertIdentitiesMatch(mServer.Requests().identify[0], identities, false) + // Due to caching + TestCase.assertEquals(mServer.Requests().identify.size, 0) } /** diff --git a/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java b/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java index 83d74b53c..402fd00ea 100644 --- a/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java +++ b/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java @@ -1,6 +1,5 @@ package com.mparticle.testutils; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.app.Activity; @@ -104,7 +103,6 @@ protected void startMParticle(MParticleOptions.Builder optionsBuilder) throws In MParticle.start(optionsBuilder.build()); mServer.setupHappyIdentify(mStartingMpid); latch.await(); - assertTrue(called.value); } protected void goToBackground() { From 405d8531c6a382d393223264433bb80ccf209ea9 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Thu, 18 Jan 2024 10:13:33 -0300 Subject: [PATCH 5/5] Adding feature flag for identity caching feature Pending read from it, as of know is disabled. --- .../com.mparticle/identity/IdentityApiStartTest.kt | 12 +++++++++--- .../java/com/mparticle/identity/IdentityApi.java | 2 +- .../java/com/mparticle/internal/ConfigManager.java | 9 +++++++++ .../com/mparticle/testutils/BaseAbstractTest.java | 2 ++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt b/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt index 69707f5a9..6117b4807 100644 --- a/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt +++ b/android-core/src/androidTest/kotlin/com.mparticle/identity/IdentityApiStartTest.kt @@ -63,12 +63,18 @@ class IdentityApiStartTest : BaseCleanInstallEachTest() { @Test @Throws(Exception::class) fun testNoInitialIdentity() { + val currentMpid = ran.nextLong() + val identities = mRandomUtils.randomUserIdentities startMParticle() - TestCase.assertEquals(mServer.Requests().identify.size, 1) + MParticle.getInstance()?.Internal()?.configManager?.setMpid(currentMpid, ran.nextBoolean()) + for ((key, value) in identities) { + AccessUtils.setUserIdentity(value, key, currentMpid) + } + com.mparticle.internal.AccessUtils.awaitMessageHandler() mServer = MockServer.getNewInstance(mContext) startMParticle() - // Due to caching - TestCase.assertEquals(mServer.Requests().identify.size, 0) + TestCase.assertEquals(mServer.Requests().identify.size, 1) + assertIdentitiesMatch(mServer.Requests().identify[0], identities, false) } /** diff --git a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java index 938ee4538..bdf61b887 100644 --- a/android-core/src/main/java/com/mparticle/identity/IdentityApi.java +++ b/android-core/src/main/java/com/mparticle/identity/IdentityApi.java @@ -364,7 +364,7 @@ private void reset() { } private boolean shouldMakeRequest(IdentityApiRequest identityRequest, boolean acceptCachedResponse, long lastIdentityCall) { - if (!acceptCachedResponse) { + if (!acceptCachedResponse || !mConfigManager.isIdentityCachingEnabled()) { return true; } boolean hasTimedOut = lastIdentityCall == -1L || (lastIdentityCall + (timeoutSeconds * 1000) > System.currentTimeMillis()); diff --git a/android-core/src/main/java/com/mparticle/internal/ConfigManager.java b/android-core/src/main/java/com/mparticle/internal/ConfigManager.java index 6199b06e7..2fe9f6826 100644 --- a/android-core/src/main/java/com/mparticle/internal/ConfigManager.java +++ b/android-core/src/main/java/com/mparticle/internal/ConfigManager.java @@ -73,6 +73,7 @@ public class ConfigManager { static final String DATAPLAN_BLOCK_USER_IDENTITIES = "id"; public static final String KIT_CONFIG_KEY = "kit_config"; static final String MIGRATED_TO_KIT_SHARED_PREFS = "is_mig_kit_sp"; + private static final String IDENTITY_CACHING_ENABLED = "identityCachingEnabled"; private static final int DEVMODE_UPLOAD_INTERVAL_MILLISECONDS = 10 * 1000; private static final int DEFAULT_MAX_ALIAS_WINDOW_DAYS = 90; @@ -92,6 +93,7 @@ public class ConfigManager { private JSONObject mProviderPersistence; private int mRampValue = -1; private int mUserBucket = -1; + private boolean identityCachingEnabled = false; private int mSessionTimeoutInterval = -1; private int mUploadInterval = -1; @@ -421,6 +423,9 @@ private synchronized void updateCoreConfig(JSONObject responseJSON, boolean newC mSendOoEvents = false; } + //TODO Read from identityCachingEnabled feature flag + editor.putBoolean(IDENTITY_CACHING_ENABLED, identityCachingEnabled); + if (responseJSON.has(ProviderPersistence.KEY_PERSISTENCE)) { setProviderPersistence(new ProviderPersistence(responseJSON, mContext)); } else { @@ -527,6 +532,10 @@ public long getInfluenceOpenTimeoutMillis() { return mInfluenceOpenTimeout; } + public boolean isIdentityCachingEnabled() { + return identityCachingEnabled; + } + private void applyConfig() { if (getLogUnhandledExceptions()) { enableUncaughtExceptionLogging(false); diff --git a/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java b/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java index 402fd00ea..83d74b53c 100644 --- a/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java +++ b/testutils/src/main/java/com/mparticle/testutils/BaseAbstractTest.java @@ -1,5 +1,6 @@ package com.mparticle.testutils; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.app.Activity; @@ -103,6 +104,7 @@ protected void startMParticle(MParticleOptions.Builder optionsBuilder) throws In MParticle.start(optionsBuilder.build()); mServer.setupHappyIdentify(mStartingMpid); latch.await(); + assertTrue(called.value); } protected void goToBackground() {