Skip to content

Commit dc664c6

Browse files
authored
Merge branch 'master' into trampoline-activity-fix
2 parents 79cc4f9 + 62ac73e commit dc664c6

File tree

11 files changed

+214
-30
lines changed

11 files changed

+214
-30
lines changed

.github/workflows/jira.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
on:
2+
issues:
3+
types: [opened]
4+
5+
name: Create Jira Issue
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
name: Create Jira Issue
11+
steps:
12+
- name: Login
13+
uses: atlassian/gajira-login@v3
14+
env:
15+
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
16+
JIRA_USER_EMAIL: ${{ secrets.JIRA_ILYA_USER_EMAIL }}
17+
JIRA_API_TOKEN: ${{ secrets.JIRA_ILYA_API_TOKEN }}
18+
19+
- name: Create
20+
id: create
21+
uses: atlassian/gajira-create@v3
22+
with:
23+
project: MOB
24+
issuetype: Bug
25+
summary: "${{ github.repository }}: #${{ github.event.issue.number }} by ${{ github.event.issue.user.login }}: ${{ github.event.issue.title }}"
26+
description: ${{ github.event.issue.body }}
27+
fields: '{"customfield_11268": {"id": "10668"} }'

app/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ apply plugin: 'kotlin-android'
33
apply plugin: 'kotlin-android-extensions'
44
apply plugin: 'jacoco'
55

6+
repositories {
7+
mavenCentral()
8+
}
9+
610
android {
711
compileSdkVersion 29
812
buildToolsVersion '29.0.3'

iterableapi/src/main/java/com/iterable/iterableapi/IterableActivityMonitor.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import android.app.Activity;
44
import android.app.Application;
55
import android.content.Context;
6-
import android.os.Build;
76
import android.os.Bundle;
87
import android.os.Handler;
98
import android.os.Looper;
109
import androidx.annotation.NonNull;
1110
import androidx.annotation.Nullable;
1211

12+
import com.iterable.iterableapi.util.DeviceInfoUtils;
13+
1314
import java.lang.ref.WeakReference;
1415
import java.util.ArrayList;
1516
import java.util.Iterator;
@@ -57,10 +58,8 @@ public void onActivityStarted(Activity activity) {
5758
@Override
5859
public void onActivityResumed(Activity activity) {
5960
currentActivity = new WeakReference<>(activity);
60-
String amazonFireTvHardware = "amazon.hardware.fire_tv";
61-
String amazonModel = Build.MODEL;
6261

63-
if (!inForeground || amazonModel.matches("AFTN") || activity.getPackageManager().hasSystemFeature(amazonFireTvHardware)) {
62+
if (!inForeground || DeviceInfoUtils.isFireTV(activity.getPackageManager())) {
6463
inForeground = true;
6564
for (WeakReference<AppStateCallback> callback : callbacks) {
6665
if (callback.get() != null) {

iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import androidx.annotation.RestrictTo;
1212
import androidx.annotation.VisibleForTesting;
1313

14+
import com.iterable.iterableapi.util.DeviceInfoUtils;
15+
1416
import org.json.JSONException;
1517
import org.json.JSONObject;
1618

@@ -38,6 +40,8 @@ public class IterableApi {
3840
private IterableNotificationData _notificationData;
3941
private String _deviceId;
4042
private boolean _firstForegroundHandled;
43+
private IterableHelper.SuccessHandler _setUserSuccessCallbackHandler;
44+
private IterableHelper.FailureHandler _setUserFailureCallbackHandler;
4145

4246
IterableApiClient apiClient = new IterableApiClient(new IterableApiAuthProvider());
4347
private @Nullable IterableInAppManager inAppManager;
@@ -276,6 +280,8 @@ private void completeUserLogin() {
276280

277281
if (config.autoPushRegistration) {
278282
registerForPush();
283+
} else if (_setUserSuccessCallbackHandler != null) {
284+
_setUserSuccessCallbackHandler.onSuccess(new JSONObject()); // passing blank json object here as onSuccess is @Nonnull
279285
}
280286

281287
getInAppManager().syncInApp();
@@ -469,7 +475,7 @@ protected void registerDeviceToken(@Nullable String email, @Nullable String user
469475
IterableLogger.e(TAG, "registerDeviceToken: applicationName is null, check that pushIntegrationName is set in IterableConfig");
470476
}
471477

472-
apiClient.registerDeviceToken(email, userId, authToken, applicationName, deviceToken, dataFields, deviceAttributes);
478+
apiClient.registerDeviceToken(email, userId, authToken, applicationName, deviceToken, dataFields, deviceAttributes, _setUserSuccessCallbackHandler, _setUserFailureCallbackHandler);
473479
}
474480
//endregion
475481

@@ -499,12 +505,26 @@ public static void initialize(@NonNull Context context, @NonNull String apiKey,
499505
IterableActivityMonitor.getInstance().addCallback(sharedInstance.activityMonitorListener);
500506

501507
if (sharedInstance.inAppManager == null) {
502-
sharedInstance.inAppManager = new IterableInAppManager(sharedInstance, sharedInstance.config.inAppHandler,
503-
sharedInstance.config.inAppDisplayInterval);
508+
sharedInstance.inAppManager = new IterableInAppManager(
509+
sharedInstance,
510+
sharedInstance.config.inAppHandler,
511+
sharedInstance.config.inAppDisplayInterval,
512+
sharedInstance.config.useInMemoryStorageForInApps);
504513
}
505514

506515
loadLastSavedConfiguration(context);
507516
IterablePushNotificationUtil.processPendingAction(context);
517+
if (DeviceInfoUtils.isFireTV(context.getPackageManager())) {
518+
try {
519+
JSONObject dataFields = new JSONObject();
520+
JSONObject deviceDetails = new JSONObject();
521+
DeviceInfoUtils.populateDeviceDetails(deviceDetails, context, sharedInstance.getDeviceId());
522+
dataFields.put(IterableConstants.KEY_FIRETV, deviceDetails);
523+
sharedInstance.apiClient.updateUser(dataFields, false);
524+
} catch (JSONException e) {
525+
IterableLogger.e(TAG, "initialize: exception", e);
526+
}
527+
}
508528
}
509529

510530
public static void setContext(Context context) {
@@ -557,10 +577,18 @@ public IterableAttributionInfo getAttributionInfo() {
557577
}
558578

559579
public void setEmail(@Nullable String email) {
560-
setEmail(email, null);
580+
setEmail(email, null, null, null);
581+
}
582+
583+
public void setEmail(@Nullable String email, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
584+
setEmail(email, null, successHandler, failureHandler);
561585
}
562586

563587
public void setEmail(@Nullable String email, @Nullable String authToken) {
588+
setEmail(email, authToken, null, null);
589+
}
590+
591+
public void setEmail(@Nullable String email, @Nullable String authToken, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
564592
//Only if passed in same non-null email
565593
if (_email != null && _email.equals(email)) {
566594
checkAndUpdateAuthToken(authToken);
@@ -575,16 +603,26 @@ public void setEmail(@Nullable String email, @Nullable String authToken) {
575603

576604
_email = email;
577605
_userId = null;
606+
_setUserSuccessCallbackHandler = successHandler;
607+
_setUserFailureCallbackHandler = failureHandler;
578608
storeAuthData();
579609

580610
onLogin(authToken);
581611
}
582612

583613
public void setUserId(@Nullable String userId) {
584-
setUserId(userId, null);
614+
setUserId(userId, null, null, null);
615+
}
616+
617+
public void setUserId(@Nullable String userId, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
618+
setUserId(userId, null, successHandler, failureHandler);
585619
}
586620

587621
public void setUserId(@Nullable String userId, @Nullable String authToken) {
622+
setUserId(userId, authToken, null, null);
623+
}
624+
625+
public void setUserId(@Nullable String userId, @Nullable String authToken, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
588626
//If same non null userId is passed
589627
if (_userId != null && _userId.equals(userId)) {
590628
checkAndUpdateAuthToken(authToken);
@@ -599,6 +637,8 @@ public void setUserId(@Nullable String userId, @Nullable String authToken) {
599637

600638
_email = null;
601639
_userId = userId;
640+
_setUserSuccessCallbackHandler = successHandler;
641+
_setUserFailureCallbackHandler = failureHandler;
602642
storeAuthData();
603643

604644
onLogin(authToken);

iterableapi/src/main/java/com/iterable/iterableapi/IterableApiClient.java

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import androidx.annotation.Nullable;
88
import androidx.core.app.NotificationManagerCompat;
99

10+
import com.iterable.iterableapi.util.DeviceInfoUtils;
11+
1012
import org.json.JSONArray;
1113
import org.json.JSONException;
1214
import org.json.JSONObject;
@@ -204,7 +206,7 @@ public void getInAppMessages(int count, @NonNull IterableHelper.IterableActionHa
204206
try {
205207
addEmailOrUserIdToJson(requestJSON);
206208
requestJSON.put(IterableConstants.ITERABLE_IN_APP_COUNT, count);
207-
requestJSON.put(IterableConstants.KEY_PLATFORM, IterableConstants.ITBL_PLATFORM_ANDROID);
209+
requestJSON.put(IterableConstants.KEY_PLATFORM, DeviceInfoUtils.isFireTV(authProvider.getContext().getPackageManager()) ? IterableConstants.ITBL_PLATFORM_OTT : IterableConstants.ITBL_PLATFORM_ANDROID);
208210
requestJSON.put(IterableConstants.ITBL_KEY_SDK_VERSION, IterableConstants.ITBL_KEY_SDK_VERSION_NUMBER);
209211
requestJSON.put(IterableConstants.ITBL_SYSTEM_VERSION, Build.VERSION.RELEASE);
210212
requestJSON.put(IterableConstants.KEY_PACKAGE_NAME, authProvider.getContext().getPackageName());
@@ -411,7 +413,7 @@ protected void disableToken(@Nullable String email, @Nullable String userId, @Nu
411413
}
412414
}
413415

414-
protected void registerDeviceToken(@Nullable String email, @Nullable String userId, @Nullable String authToken, @NonNull String applicationName, @NonNull String deviceToken, @Nullable JSONObject dataFields, HashMap<String, String> deviceAttributes) {
416+
protected void registerDeviceToken(@Nullable String email, @Nullable String userId, @Nullable String authToken, @NonNull String applicationName, @NonNull String deviceToken, @Nullable JSONObject dataFields, HashMap<String, String> deviceAttributes, @Nullable final IterableHelper.SuccessHandler successHandler, @Nullable final IterableHelper.FailureHandler failureHandler) {
415417
Context context = authProvider.getContext();
416418
JSONObject requestJSON = new JSONObject();
417419
try {
@@ -427,18 +429,7 @@ protected void registerDeviceToken(@Nullable String email, @Nullable String user
427429

428430
dataFields.put(IterableConstants.FIREBASE_TOKEN_TYPE, IterableConstants.MESSAGING_PLATFORM_FIREBASE);
429431
dataFields.put(IterableConstants.FIREBASE_COMPATIBLE, true);
430-
dataFields.put(IterableConstants.DEVICE_BRAND, Build.BRAND); //brand: google
431-
dataFields.put(IterableConstants.DEVICE_MANUFACTURER, Build.MANUFACTURER); //manufacturer: samsung
432-
dataFields.put(IterableConstants.DEVICE_SYSTEM_NAME, Build.DEVICE); //device name: toro
433-
dataFields.put(IterableConstants.DEVICE_SYSTEM_VERSION, Build.VERSION.RELEASE); //version: 4.0.4
434-
dataFields.put(IterableConstants.DEVICE_MODEL, Build.MODEL); //device model: Galaxy Nexus
435-
dataFields.put(IterableConstants.DEVICE_SDK_VERSION, Build.VERSION.SDK_INT); //sdk version/api level: 15
436-
437-
dataFields.put(IterableConstants.DEVICE_ID, authProvider.getDeviceId()); // Random UUID
438-
dataFields.put(IterableConstants.DEVICE_APP_PACKAGE_NAME, context.getPackageName());
439-
dataFields.put(IterableConstants.DEVICE_APP_VERSION, IterableUtil.getAppVersion(context));
440-
dataFields.put(IterableConstants.DEVICE_APP_BUILD, IterableUtil.getAppVersionCode(context));
441-
dataFields.put(IterableConstants.DEVICE_ITERABLE_SDK_VERSION, IterableConstants.ITBL_KEY_SDK_VERSION_NUMBER);
432+
DeviceInfoUtils.populateDeviceDetails(dataFields, context, authProvider.getDeviceId());
442433
dataFields.put(IterableConstants.DEVICE_NOTIFICATIONS_ENABLED, NotificationManagerCompat.from(context).areNotificationsEnabled());
443434

444435
JSONObject device = new JSONObject();
@@ -453,7 +444,7 @@ protected void registerDeviceToken(@Nullable String email, @Nullable String user
453444
requestJSON.put(IterableConstants.KEY_PREFER_USER_ID, true);
454445
}
455446

456-
sendPostRequest(IterableConstants.ENDPOINT_REGISTER_DEVICE_TOKEN, requestJSON, authToken);
447+
sendPostRequest(IterableConstants.ENDPOINT_REGISTER_DEVICE_TOKEN, requestJSON, authToken, successHandler, failureHandler);
457448
} catch (JSONException e) {
458449
IterableLogger.e(TAG, "registerDeviceToken: exception", e);
459450
}

iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ public class IterableConfig {
7171
*/
7272
final String[] allowedProtocols;
7373

74+
/**
75+
* This controls whether the in-app content should be saved to disk, or only kept in memory.
76+
* By default, the SDK will save in-apps to disk.
77+
*/
78+
final boolean useInMemoryStorageForInApps;
79+
7480
private IterableConfig(Builder builder) {
7581
pushIntegrationName = builder.pushIntegrationName;
7682
urlHandler = builder.urlHandler;
@@ -83,6 +89,7 @@ private IterableConfig(Builder builder) {
8389
authHandler = builder.authHandler;
8490
expiringAuthTokenRefreshPeriod = builder.expiringAuthTokenRefreshPeriod;
8591
allowedProtocols = builder.allowedProtocols;
92+
useInMemoryStorageForInApps = builder.useInMemoryStorageForInApps;
8693
}
8794

8895
public static class Builder {
@@ -97,6 +104,8 @@ public static class Builder {
97104
private IterableAuthHandler authHandler;
98105
private long expiringAuthTokenRefreshPeriod = 60000L;
99106
private String[] allowedProtocols = new String[0];
107+
private boolean useInMemoryStorageForInApps = false;
108+
100109
public Builder() {}
101110

102111
/**
@@ -217,6 +226,17 @@ public Builder setAllowedProtocols(@NonNull String[] allowedProtocols) {
217226
return this;
218227
}
219228

229+
/**
230+
* Set whether the SDK should store in-apps only in memory, or in file storage
231+
* @param useInMemoryStorageForInApps `true` will have in-apps be only in memory
232+
*/
233+
234+
@NonNull
235+
public Builder setUseInMemoryStorageForInApps(boolean useInMemoryStorageForInApps) {
236+
this.useInMemoryStorageForInApps = useInMemoryStorageForInApps;
237+
return this;
238+
}
239+
220240
@NonNull
221241
public IterableConfig build() {
222242
return new IterableConfig(this);

iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public final class IterableConstants {
5454
public static final String KEY_USER_TEXT = "userText";
5555
public static final String KEY_INBOX_SESSION_ID = "inboxSessionId";
5656
public static final String KEY_OFFLINE_MODE = "offlineMode";
57+
public static final String KEY_FIRETV = "FireTV";
5758

5859
//API Endpoint Key Constants
5960
public static final String ENDPOINT_DISABLE_DEVICE = "users/disableDevice";
@@ -245,6 +246,7 @@ public final class IterableConstants {
245246

246247
public static final String ITBL_KEY_SDK_VERSION = "SDKVersion";
247248
public static final String ITBL_PLATFORM_ANDROID = "Android";
249+
public static final String ITBL_PLATFORM_OTT = "OTT";
248250
public static final String ITBL_KEY_SDK_VERSION_NUMBER = BuildConfig.ITERABLE_SDK_VERSION;
249251
public static final String ITBL_SYSTEM_VERSION = "systemVersion";
250252

iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.json.JSONException;
1818
import org.json.JSONObject;
1919

20+
import java.io.File;
2021
import java.util.ArrayList;
2122
import java.util.Collections;
2223
import java.util.Comparator;
@@ -50,11 +51,11 @@ public interface Listener {
5051
private long lastInAppShown = 0;
5152
private boolean autoDisplayPaused = false;
5253

53-
IterableInAppManager(IterableApi iterableApi, IterableInAppHandler handler, double inAppDisplayInterval) {
54+
IterableInAppManager(IterableApi iterableApi, IterableInAppHandler handler, double inAppDisplayInterval, boolean useInMemoryStorageForInApps) {
5455
this(iterableApi,
5556
handler,
5657
inAppDisplayInterval,
57-
new IterableInAppFileStorage(iterableApi.getMainActivityContext()),
58+
IterableInAppManager.getInAppStorageModel(iterableApi, useInMemoryStorageForInApps),
5859
IterableActivityMonitor.getInstance(),
5960
new IterableInAppDisplayer(IterableActivityMonitor.getInstance()));
6061
}
@@ -435,6 +436,26 @@ private void handleIterableCustomAction(String actionName, IterableInAppMessage
435436
}
436437
}
437438

439+
private static IterableInAppStorage getInAppStorageModel(IterableApi iterableApi, boolean useInMemoryForInAppStorage) {
440+
if (useInMemoryForInAppStorage) {
441+
checkAndDeleteUnusedInAppFileStorage(iterableApi.getMainActivityContext());
442+
443+
return new IterableInAppMemoryStorage();
444+
} else {
445+
return new IterableInAppFileStorage(iterableApi.getMainActivityContext());
446+
}
447+
}
448+
449+
private static void checkAndDeleteUnusedInAppFileStorage(Context context) {
450+
File sdkFilesDirectory = IterableUtil.getSDKFilesDirectory(context);
451+
File inAppContentFolder = IterableUtil.getDirectory(sdkFilesDirectory, "IterableInAppFileStorage");
452+
File inAppBlob = new File(inAppContentFolder, "itbl_inapp.json");
453+
454+
if (inAppBlob.exists()) {
455+
inAppBlob.delete();
456+
}
457+
}
458+
438459
@Override
439460
public void onSwitchToForeground() {
440461
if (IterableUtil.currentTimeMillis() - lastSyncTime > MOVE_TO_FOREGROUND_SYNC_INTERVAL_MS) {

iterableapi/src/main/java/com/iterable/iterableapi/IterableUtil.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@
1111

1212
import java.io.File;
1313

14-
class IterableUtil {
14+
public class IterableUtil {
1515
@VisibleForTesting
1616
static IterableUtilImpl instance = new IterableUtilImpl();
1717

18+
private IterableUtil() { }
19+
1820
static long currentTimeMillis() {
1921
return instance.currentTimeMillis();
2022
}
2123

22-
static String getAppVersion(Context context) {
24+
public static String getAppVersion(Context context) {
2325
return instance.getAppVersion(context);
2426
}
2527

26-
static String getAppVersionCode(Context context) {
28+
public static String getAppVersionCode(Context context) {
2729
return instance.getAppVersionCode(context);
2830
}
2931

0 commit comments

Comments
 (0)