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

[MOB-15817] Add getUrlVariables public API #59

Merged
merged 17 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class SharedViewModel : ViewModel() {
private val _ecidLegacyText = MutableLiveData<String>("")
val ecidLegacyText: LiveData<String> = _ecidLegacyText

private val _urlVariablesText = MutableLiveData<String>("")
val urlVariablesText: LiveData<String> = _urlVariablesText

private val _identitiesText = MutableLiveData<String>("")
val identitiesText: LiveData<String> = _identitiesText

Expand All @@ -43,6 +46,10 @@ class SharedViewModel : ViewModel() {
_ecidLegacyText.value = value
}

fun setUrlVariablesValue(value: String) {
_urlVariablesText.value = value
}

fun setIdentitiesValue(value: String) {
_identitiesText.value = value
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ class GetIdentityFragment : Fragment() {
}
)

val urlVariablesTextView = root.findViewById<TextView>(R.id.text_url_variables)
sharedViewModel.urlVariablesText.observe(
viewLifecycleOwner,
Observer {
urlVariablesTextView.text = it
}
)

val identitiesTextView = root.findViewById<TextView>(R.id.text_identities)
sharedViewModel.identitiesText.observe(
viewLifecycleOwner,
Expand Down Expand Up @@ -85,6 +93,21 @@ class GetIdentityFragment : Fragment() {
sharedViewModel.setEcidLegacyValue(if (resultSecondary != null) "legacy: $resultSecondary" else "")
}

root.findViewById<Button>(R.id.btn_get_url_variables).setOnClickListener {
val latch = CountDownLatch(2)
var resultUrlVariables: String? = null

com.adobe.marketing.mobile.edge.identity.Identity.getUrlVariables { urlVariables ->
Log.d("Home", "Got UrlVariables String: $urlVariables")
resultUrlVariables = urlVariables
latch.countDown()
}

latch.await(1, TimeUnit.SECONDS)

sharedViewModel.setUrlVariablesValue(if (resultUrlVariables != null) "urlVariablesString: $resultUrlVariables" else "urlVariablesString: not found")
}

root.findViewById<Button>(R.id.btn_get_identities).setOnClickListener {
val latch = CountDownLatch(1)
var result: String? = null
Expand Down
25 changes: 25 additions & 0 deletions code/app/src/main/res/layout/fragment_get_identity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,38 @@

</LinearLayout>

<Button
android:id="@+id/btn_get_url_variables"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_get_url_variables"
android:layout_gravity="center"
android:layout_marginTop="18dp"
/>

<TextView
android:id="@+id/text_url_variables"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:textAlignment="center"
android:textSize="12sp"
android:layout_gravity="center"
android:scrollbars="vertical"
android:background="@drawable/border"
/>

<Button
android:id="@+id/btn_reset_identities"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_reset_identities"
android:layout_gravity="center"
android:layout_marginTop="18dp"
android:backgroundTint="@android:color/holo_red_light"
android:textColor="@android:color/white"
/>

<Button
Expand Down
1 change: 1 addition & 0 deletions code/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<string name="menu_custom_identity">Set Custom Identity</string>
<string name="menu_multiple_identity">Test Multiple Identities</string>
<string name="btn_get_ecid">Get ECID</string>
<string name="btn_get_url_variables">Get URL Variables</string>
<string name="btn_get_identities">Get Identities</string>
<string name="btn_reset_identities">Reset Identities</string>
<string name="label_identifier">Identifier: </string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ public void call(Object o) {
resetTestExpectations();
}

/**
* Updates configuration shared state with an orgId
*/
static void setupConfiguration() throws Exception {
HashMap<String, Object> config = new HashMap<String, Object>() {
{
put("experienceCloud.org", "testOrg@AdobeOrg");
}
};
MobileCore.updateConfiguration(config);
TestHelper.waitForThreads(2000);
}

/**
* Set the ECID in persistence for Identity Direct extension.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import static com.adobe.marketing.mobile.TestHelper.*;
import static com.adobe.marketing.mobile.edge.identity.IdentityFunctionalTestUtil.registerEdgeIdentityExtension;
import static com.adobe.marketing.mobile.edge.identity.IdentityFunctionalTestUtil.setupConfiguration;
import static com.adobe.marketing.mobile.edge.identity.IdentityTestUtil.*;
import static org.junit.Assert.*;

Expand Down Expand Up @@ -282,6 +283,29 @@ public void testGetExperienceCloudId_nullCallback() {
}
}

// --------------------------------------------------------------------------------------------
// Tests for getUrlVariables API
// --------------------------------------------------------------------------------------------

@Test
public void testGetUrlVariables() throws Exception {
// test
setupConfiguration();
String urlVariables = getUrlVariablesSync();

assertNotNull(urlVariables);
}

@Test
public void testGetUrlVariables_nullCallback() {
// test
try {
Identity.getUrlVariables(null); // should not crash
} catch (Exception e) {
fail();
}
}

// --------------------------------------------------------------------------------------------
// Tests for getIdentities API
// --------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,28 @@ static boolean isRequestIdentityEvent(final Event event) {
);
}

/**
* Reads the url variables flag from the event data, returns false if not present
*
* @param event the event to verify
* @return true if urlVariables key is present in the event data
addb marked this conversation as resolved.
Show resolved Hide resolved
*/
static boolean hasUrlVariablesFlag(final Event event) {
addb marked this conversation as resolved.
Show resolved Hide resolved
addb marked this conversation as resolved.
Show resolved Hide resolved
if (event == null || event.getEventData() == null) {
return false;
}
boolean getUrlVariablesFlag = false;

try {
Object urlVariablesFlagObject = event.getEventData().get(IdentityConstants.EventDataKeys.URL_VARIABLES);
getUrlVariablesFlag = urlVariablesFlagObject != null && (boolean) urlVariablesFlagObject;
} catch (ClassCastException e) {
return false;
addb marked this conversation as resolved.
Show resolved Hide resolved
}

return getUrlVariablesFlag;
}

/**
* Checks if the provided {@code event} is of type {@link IdentityConstants.EventType#GENERIC_IDENTITY} and source {@link IdentityConstants.EventSource#REQUEST_RESET}
*
Expand Down Expand Up @@ -127,4 +149,34 @@ static ECID getECID(final Map<String, Object> identityDirectSharedState) {

return legacyEcid;
}

/**
* Extracts the Experience Cloud Org Id from the Configuration shared state
*
* @param configurationSharedState the configuration shared state data
* @return the Experience Cloud Org Id or null if not found or unable to parse the payload
*/
static String getOrgId(final Map<String, Object> configurationSharedState) {
addb marked this conversation as resolved.
Show resolved Hide resolved
String orgId = null;

if (configurationSharedState == null) {
return orgId;
}

try {
orgId =
(String) configurationSharedState.get(
IdentityConstants.SharedState.Configuration.EXPERIENCE_CLOUD_ORGID
);
} catch (ClassCastException e) {
MobileCore.log(
LoggingMode.DEBUG,
LOG_TAG,
"EventUtils - Failed to extract Experience ORG ID from Configuration shared state, expected String: " +
e.getLocalizedMessage()
);
}

return orgId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import com.adobe.marketing.mobile.ExtensionErrorCallback;
import com.adobe.marketing.mobile.LoggingMode;
import com.adobe.marketing.mobile.MobileCore;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Defines the public APIs for the AEP Edge Identity extension.
Expand Down Expand Up @@ -136,6 +138,91 @@ public void call(Event responseEvent) {
);
}

/**
* Returns the identifiers in URL query parameter format for consumption in hybrid mobile applications.
* There is no leading &amp; or ? punctuation as the caller is responsible for placing the variables in their resulting URL in the correct locations.
addb marked this conversation as resolved.
Show resolved Hide resolved
addb marked this conversation as resolved.
Show resolved Hide resolved
* If an error occurs while retrieving the URL variables, the AdobeCallbackWithError is called with a null value and AdobeError instance.
* If AdobeCallback is provided then callback is not called in case of error.
* Otherwise, the encoded string is returned, for ex: "adobe_mc=TS%3DTIMESTAMP_VALUE%7CMCMID%3DYOUR_ECID%7CMCORGID%3D9YOUR_EXPERIENCE_CLOUD_ID"
* The {@code adobe_mc} attribute is an URL encoded list that contains:
* <ul>
* <li>TS: a timestamp taken when the request was made</li>
* <li>MCID: Experience Cloud ID (ECID)</li>
* <li>MCORGID: Experience Cloud Org ID</li>
* </ul>
*
* @param callback {@link AdobeCallback} of {@code String} invoked with a value containing the identifiers in query parameter format.
* If an {@link AdobeCallbackWithError} is provided, an {@link AdobeError} can be returned in the
* eventuality of any error that occurred while getting the identifiers query string
*/
public static void getUrlVariables(final AdobeCallback<String> callback) {
if (callback == null) {
MobileCore.log(
LoggingMode.DEBUG,
LOG_TAG,
"Identity - Unexpected null callback, provide a callback to retrieve current visitor identifiers (URLVariables) query string."
);
return;
}

final Event event = new Event.Builder(
IdentityConstants.EventNames.IDENTITY_REQUEST_URL_VARIABLES,
IdentityConstants.EventType.EDGE_IDENTITY,
IdentityConstants.EventSource.REQUEST_IDENTITY
)
.setEventData(
new HashMap<String, Object>() {
{
put(IdentityConstants.EventDataKeys.URL_VARIABLES, true);
}
}
)
.build();

final ExtensionErrorCallback<ExtensionError> errorCallback = new ExtensionErrorCallback<ExtensionError>() {
@Override
public void error(final ExtensionError extensionError) {
returnError(callback, extensionError);
MobileCore.log(
LoggingMode.DEBUG,
LOG_TAG,
String.format(
"Identity - Failed to dispatch %s event: Error : %s.",
IdentityConstants.EventNames.IDENTITY_REQUEST_URL_VARIABLES,
extensionError.getErrorName()
)
);
}
};

MobileCore.dispatchEventWithResponseCallback(
event,
new AdobeCallback<Event>() {
@Override
public void call(Event responseEvent) {
if (responseEvent == null || responseEvent.getEventData() == null) {
returnError(callback, AdobeError.UNEXPECTED_ERROR);
return;
}

final Map<String, Object> data = responseEvent.getEventData();
try {
String urlVariableString = (String) data.get(IdentityConstants.EventDataKeys.URL_VARIABLES);
if (urlVariableString == null) {
returnError(callback, AdobeError.UNEXPECTED_ERROR);
return;
}
callback.call(urlVariableString);
} catch (ClassCastException e) {
returnError(callback, AdobeError.UNEXPECTED_ERROR);
return;
}
}
},
errorCallback
);
}

/**
* Updates the currently known {@link IdentityMap} within the SDK.
* The Identity extension will merge the received identifiers with the previously saved one in an additive manner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,19 @@ final class EventType {
private EventType() {}
}

final class EventDataKeys {

static final String URL_VARIABLES = "urlvariables";

private EventDataKeys() {}
}

final class EventNames {

static final String IDENTITY_REQUEST_IDENTITY_ECID = "Edge Identity Request ECID";
static final String IDENTITY_REQUEST_URL_VARIABLES = "Edge Identity Request URL Variables";
static final String IDENTITY_RESPONSE_CONTENT_ONE_TIME = "Edge Identity Response Content One Time";
static final String IDENTITY_RESPONSE_URL_VARIABLES = "Edge Identity Response URL Variables";
static final String UPDATE_IDENTITIES = "Edge Identity Update Identities";
static final String REMOVE_IDENTITIES = "Edge Identity Remove Identities";
static final String REQUEST_IDENTITIES = "Edge Identity Request Identities";
Expand All @@ -66,6 +75,14 @@ final class Hub {
private Hub() {}
}

final class Configuration {

static final String NAME = "com.adobe.module.configuration";
static final String EXPERIENCE_CLOUD_ORGID = "experienceCloud.org";

private Configuration() {}
}

final class IdentityDirect {

static final String NAME = "com.adobe.module.identity";
Expand Down Expand Up @@ -106,5 +123,15 @@ final class DataStoreKey {
private DataStoreKey() {}
}

final class UrlKeys {

static final String TS = "TS";
static final String EXPERIENCE_CLOUD_ORG_ID = "MCORGID";
static final String EXPERIENCE_CLOUD_ID = "MCMID";
static final String PAYLOAD = "adobe_mc";

private UrlKeys() {}
}

private IdentityConstants() {}
}
Loading