Skip to content

Commit 7ee5748

Browse files
authored
Merge pull request #646 from Iterable/encryption
[MOB - 6793] - Encryption branch Merge to Master | CI Fixed
2 parents 1ed0c34 + d9917a4 commit 7ee5748

File tree

16 files changed

+403
-48
lines changed

16 files changed

+403
-48
lines changed

CHANGELOG.md

+149-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,158 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1212
#### Changed
1313
- nothing yet
1414

15+
## [3.4.16](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.16)
1516
#### Fixed
16-
- nothing yet
17+
- SDK now handles `null` scenarios preventing crashes when `IterableEncryptedSharedPreference` creation fails.
18+
- Updated crypto library to version [1.1.0-alpha06](https://developer.android.com/jetpack/androidx/releases/security#1.1.0-alpha06). [1.1.0-alpha05](https://developer.android.com/jetpack/androidx/releases/security#1.1.0-alpha05) solves a race condition during creation process.
1719

18-
## [3.4.9](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.9)
20+
## [3.4.15](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.15)
21+
#### Added
22+
23+
This release allows you to use projects hosted on Iterable's EU data center. If your project is hosted on Iterable's [European data center (EUDC)](https://support.iterable.com/hc/articles/17572750887444), configure the SDK to use Iterable's EU-based API endpoints:
24+
25+
_Java_
26+
27+
```java
28+
IterableConfig config = new IterableConfig.Builder()
29+
// ... other configuration options ...
30+
.setDataRegion(IterableDataRegion.EU)
31+
.build();
32+
IterableApi.initialize(context, "<YOUR_API_KEY>", config);
33+
```
34+
35+
_Kotlin_
36+
37+
```kotlin
38+
val configBuilder = IterableConfig.Builder()
39+
// ... other configuration options ...
40+
.setDataRegion(IterableDataRegion.EU)
41+
.build();
42+
IterableApi.initialize(context, "<YOUR_API_KEY>", config);
43+
```
44+
45+
#### Fixed
46+
- Addressed React Native SDK push notification deep linking issues where the app would restart instead of resuming the last activity upon being backgrounded.
47+
- Resolves an additional push notification problem wherein the customActionHandler and urlHandler were not being invoked in specific scenarios, as documented in issue #470. (Credit to @tnortman-jabra for the report and the fix)
48+
49+
## [3.4.14](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.14)
50+
#### Added
51+
- `IterableInAppManager.setRead` now accepts `IterableHelper.FailureHandler failureHandler`
1952

53+
#### Fixed
54+
- Fixes an issue where `IterableInAppManager.removeMessage` caused build failure in React Native SDK pointing to legacy method calls.
55+
- Fixes an issue where custom action handlers were not invoked when tapping on push notification when the app is in background.
56+
57+
## [3.4.13](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.13)
58+
#### Added
59+
- `IterableInAppManager.setRead` now accepts `IterableHelper.SuccessHandler successHandler`.
60+
- `IterableApi.inAppConsume` now accepts `IterableHelper.SuccessHandler successHandler` and `IterableHelper.FailureHandler failureHandler`.
61+
62+
## [3.4.12](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.12)
63+
#### Added
64+
- `setEmail` and `setUserId` now accepts `IterableHelper.SuccessHandler successHandler` and `IterableHelper.FailureHandler failureHandler`.
65+
66+
#### Changed
67+
- OTT devices (FireTV) will now register as `OTT` device instead of `Android` under user's devices.
68+
69+
## [3.4.11](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.11)
70+
71+
#### Added
72+
73+
- Custom push notification sounds! To play a custom sound for a push notification, add a sound file to your app's `res/raw` folder and specify that same filename when setting up a template in Iterable.
74+
75+
Some important notes about custom sounds and notification channels:
76+
77+
- Android API level 26 introduced [notification channels](https://developer.android.com/develop/ui/views/notifications/channels). Every notification must be assigned to a channel.
78+
- Each custom sound you add to an Iterable template creates a new Android notification channel. The notification channel's name matches the filename of the sound (without its extension).
79+
- To ensure sensible notification channel names for end users, give friendly names to your sound files. For example, a custom sound file with name `Paid.mp3` creates a notification channel called `Paid`. The end user can see this notification channel name in their device's notification channel settings.
80+
- Be sure to place the corresponding sound file in your app's `res/raw` directory.
81+
82+
- To help you access a user's `email` address, `userId`, and `authToken`, the SDK now provides convenience methods: `getEmail()`, `getUserId()`, and `getAuthToken()`.
83+
84+
#### Changed
85+
86+
- Updated the [Security library](https://developer.android.com/topic/security/data) and improved `EncryptedSharedPreferences` handling.
87+
88+
To work around a [known Android issue](https://issuetracker.google.com/issues/164901843) that can cause crashes when creating `EncryptedSharedPreferences`, we've upgraded `androidx.security.crypto` from version `1.0.0` to `1.1.0-alpha04`. When `EncryptedSharedPreferences` cannot be created, the SDK now uses `SharedPreferences` (unencrypted).
89+
90+
If your app requires encryption, you can prevent this fallback to `SharedPreferences` by setting the `encryptionEnforced` configuration flag to `true`. However, if you enable this flag and `EncryptedSharedPreferences` cannot be created, an exception will be thrown.
91+
92+
- Improved JWT token management. This change addresses an issue where `null` values could prevent the refresh of a JWT token.
93+
94+
#### Fixed
95+
96+
- Fixed an issue which could prevent in-app messages from respecting the **Position** value selected when setting up the template (top / center / bottom / full).
97+
98+
- Fixed crashes that sometimes happened during in-app message animations.
99+
100+
## [3.4.10](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.10)
101+
This release includes support for encrypting some data at rest, and an option to
102+
store in-app messages in memory.
103+
104+
#### Encrypted data
105+
106+
In Android apps with `minSdkVersion` 23 or higher ([Android 6.0](https://developer.android.com/studio/releases/platforms#6.0))
107+
Iterable's Android SDK now encrypts the following fields when storing them at
108+
rest:
109+
110+
- `email` — The user's email address.
111+
- `userId` — The user's ID.
112+
- `authToken` — The JWT used to authenticate the user with Iterable's API.
113+
114+
(Note that Iterable's Android SDK does not store the last push payload at
115+
rest—before or after this update.)
116+
117+
For more information about this encryption in Android, examine the source code
118+
for Iterable's Android SDK: [`IterableKeychain`](https://github.com/Iterable/iterable-android-sdk/blob/master/iterableapi/src/main/java/com/iterable/iterableapi/IterableKeychain.kt).
119+
120+
#### Storing in-app messages in memory
121+
122+
This release also allows you to have your Android apps (regardless of `minSdkVersion`)
123+
store in-app messages in memory, rather than in an unencrypted local file.
124+
However, an unencrypted local file is still the default option.
125+
126+
To store in-app messages in memory, set the `setUseInMemoryStorageForInApps(true)`
127+
SDK configuration option (defaults to `false`):
128+
129+
_Java_
130+
131+
```java
132+
IterableConfig.Builder configBuilder = new IterableConfig.Builder()
133+
// ... other configuration options ...
134+
.setUseInMemoryStorageForInApps(true);
135+
IterableApi.initialize(context, "<YOUR_API_KEY>", config);
136+
```
137+
138+
_Kotlin_
139+
140+
```kotlin
141+
val configBuilder = IterableConfig.Builder()
142+
// ... other configuration options ...
143+
.setUseInMemoryStorageForInApps(true);
144+
IterableApi.initialize(context, "<YOUR_API_KEY>", configBuilder.build());
145+
```
146+
147+
When users upgrade to a version of your Android app that uses this version of
148+
the SDK (or higher), and you've set this configuration option to `true`, the
149+
local file used for in-app message storage (if it already exists) is deleted
150+
However, no data is lost.
151+
152+
#### Android upgrade instructions
153+
154+
If your app targets API level 23 or higher, this is a standard SDK upgrade, with
155+
no special instructions.
156+
157+
If your app targets an API level less than 23, you'll need to make the following
158+
changes to your project (which allow your app to build, even though it won't
159+
encrypt data):
160+
161+
1. In `AndroidManifest.xml`, add `<uses-sdk tools:overrideLibrary="androidx.security" />`
162+
2. In your app's `app/build.gradle`:
163+
- Add `multiDexEnabled true` to the `default` object, under `android`.
164+
- Add `implementation androidx.multidex:multidex:2.0.1` to the `dependencies`.
165+
166+
## [3.4.9](https://github.com/Iterable/iterable-android-sdk/releases/tag/3.4.9)
20167
#### Added
21168
- Added new methods for `setEmail`, `setUserId` and `updateEmail` which accepts `authToken`, providing more ways to pass `authToken` to SDK
22169
- Added two interface methods - `onTokenRegistrationSuccessful` and `onTokenRegistrationFailed`. Override these methods to see if authToken was successfully received by the SDK.

app/build.gradle

+12
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,25 @@ android {
2020
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2121
multiDexEnabled true
2222
}
23+
2324
buildTypes {
2425
release {
2526
minifyEnabled false
2627
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
2728
}
29+
2830
debug {
2931
testCoverageEnabled true
3032
}
3133
}
3234

3335
testOptions.unitTests.includeAndroidResources = true
36+
3437
compileOptions {
3538
sourceCompatibility = 1.8
3639
targetCompatibility = 1.8
3740
}
41+
3842
kotlinOptions {
3943
jvmTarget = "1.8"
4044
}
@@ -73,9 +77,11 @@ dependencies {
7377
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
7478
androidTestImplementation 'br.com.concretesolutions:kappuccino:1.2.1'
7579
}
80+
7681
tasks.withType(Test) {
7782
jacoco.includeNoLocationClasses = true
7883
}
84+
7985
task jacocoDebugTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
8086
group = "reporting"
8187
description = "Generate unified Jacoco code coverage report"
@@ -103,12 +109,14 @@ task jacocoDebugTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest'])
103109
'**/*$ModuleAdapter.class',
104110
'**/*$ViewInjector*.class',
105111
]
112+
106113
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug/classes", excludes: fileFilter) //we use "debug" build type for test coverage (can be other)
107114
def sdkTree = fileTree(dir: "${buildDir}/../../iterableapi/build/intermediates/javac/debug/classes", excludes: fileFilter)
108115
def sdkUiTree = fileTree(dir: "${buildDir}/../../iterableapi-ui/build/intermediates/javac/debug/classes", excludes: fileFilter)
109116
def mainSrc = "${project.projectDir}/src/main/java"
110117
def sdkSrc = "${project.projectDir}/../iterableapi/src/main/java"
111118
def sdkUiSrc = "${project.projectDir}/../iterableapi-ui/src/main/java"
119+
112120
sourceDirectories.from = files([mainSrc])
113121
classDirectories.from = files([debugTree])
114122
additionalSourceDirs.from = files([sdkSrc, sdkUiSrc])
@@ -121,11 +129,13 @@ task jacocoDebugTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest'])
121129
task jacocoDebugAndroidTestReport(type: JacocoReport, dependsOn: ['connectedCheck']) {
122130
group = "reporting"
123131
description = "Generate Jacoco code coverage report for instumentation tests"
132+
124133
reports {
125134
xml.enabled = true
126135
html.enabled = true
127136
csv.enabled = false
128137
}
138+
129139
def fileFilter = [
130140
'**/*Test*.*',
131141
'**/AutoValue_*.*',
@@ -145,12 +155,14 @@ task jacocoDebugAndroidTestReport(type: JacocoReport, dependsOn: ['connectedChec
145155
'**/*$ModuleAdapter.class',
146156
'**/*$ViewInjector*.class',
147157
]
158+
148159
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug/classes", excludes: fileFilter) //we use "debug" build type for test coverage (can be other)
149160
def sdkTree = fileTree(dir: "${buildDir}/../../iterableapi/build/intermediates/javac/debug/classes", excludes: fileFilter)
150161
def sdkUiTree = fileTree(dir: "${buildDir}/../../iterableapi-ui/build/intermediates/javac/debug/classes", excludes: fileFilter)
151162
def mainSrc = "${project.projectDir}/src/main/java"
152163
def sdkSrc = "${project.projectDir}/../iterableapi/src/main/java"
153164
def sdkUiSrc = "${project.projectDir}/../iterableapi-ui/src/main/java"
165+
154166
sourceDirectories.from = files([mainSrc])
155167
classDirectories.from = files([debugTree])
156168
additionalSourceDirs.from = files([sdkSrc, sdkUiSrc])
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:tools="http://schemas.android.com/tools"
3-
package="iterable.com.iterableapi">
4-
<uses-sdk tools:overrideLibrary="br.com.concretesolutions.kappuccino,android_libs.ub_uiautomator"/>
2+
<manifest xmlns:tools="http://schemas.android.com/tools" package="iterable.com.iterableapi">
3+
<uses-sdk tools:overrideLibrary="br.com.concretesolutions.kappuccino,android_libs.ub_uiautomator,androidx.security"/>
54
</manifest>

app/src/main/AndroidManifest.xml

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
34
package="com.iterable.iterableapi.testapp">
4-
5+
<uses-sdk tools:overrideLibrary="androidx.security"/>
56
<application
67
android:allowBackup="true"
78
android:icon="@mipmap/ic_launcher"
@@ -14,10 +15,8 @@
1415
android:theme="@style/AppTheme.NoActionBar">
1516
<intent-filter>
1617
<action android:name="android.intent.action.MAIN" />
17-
1818
<category android:name="android.intent.category.LAUNCHER" />
1919
</intent-filter>
2020
</activity>
2121
</application>
22-
23-
</manifest>
22+
</manifest>

iterableapi-ui/build.gradle

+3-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ ext {
4848
siteUrl = 'https://github.com/Iterable/iterable-android-sdk'
4949
gitUrl = 'https://github.com/Iterable/iterable-android-sdk.git'
5050

51-
libraryVersion = '3.4.9'
51+
libraryVersion = '3.4.16'
5252

5353
developerId = 'davidtruong'
5454
developerName = 'David Truong'
@@ -60,7 +60,8 @@ ext {
6060
}
6161

6262
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
63-
if(hasProperty("mavenPublishEnabled")) {
63+
64+
if (hasProperty("mavenPublishEnabled")) {
6465
apply from: '../maven-push.gradle'
6566
}
6667

iterableapi-ui/src/main/AndroidManifest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools"
23
package="com.iterable.iterableapi.ui">
4+
<uses-sdk tools:overrideLibrary="androidx.security"/>
35
<application>
46
<activity
57
android:name=".inbox.IterableInboxActivity"

iterableapi-ui/src/main/java/com/iterable/iterableapi/ui/inbox/IterableInboxFragment.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ public void onListItemTapped(@NonNull IterableInAppMessage message) {
255255

256256
@Override
257257
public void onListItemDeleted(@NonNull IterableInAppMessage message, @NonNull IterableInAppDeleteActionType source) {
258-
IterableApi.getInstance().getInAppManager().removeMessage(message, source, IterableInAppLocation.INBOX);
258+
IterableApi.getInstance().getInAppManager().removeMessage(message, source, IterableInAppLocation.INBOX, null, null);
259259
}
260260

261261
@Override

iterableapi/build.gradle

+14-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ android {
77
compileSdkVersion 29
88
buildToolsVersion '29.0.3'
99

10+
compileOptions {
11+
sourceCompatibility 1.8
12+
targetCompatibility 1.8
13+
}
14+
1015
defaultConfig {
1116
minSdkVersion 16
1217
targetSdkVersion 27
1318

14-
buildConfigField "String", "ITERABLE_SDK_VERSION", "\"3.4.9\""
19+
buildConfigField "String", "ITERABLE_SDK_VERSION", "\"3.4.16\""
1520

1621
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1722
}
23+
1824
buildTypes {
1925
release {
2026
minifyEnabled false
@@ -25,11 +31,13 @@ android {
2531
multiDexEnabled true
2632
}
2733
}
34+
2835
testOptions.unitTests.all {
2936
testLogging {
3037
exceptionFormat "full"
3138
}
3239
}
40+
3341
testOptions.unitTests.includeAndroidResources = true
3442
}
3543

@@ -39,6 +47,7 @@ dependencies {
3947
api 'androidx.appcompat:appcompat:1.0.0'
4048
api 'androidx.annotation:annotation:1.0.0'
4149
api 'com.google.firebase:firebase-messaging:20.3.0'
50+
implementation "androidx.security:security-crypto:1.1.0-alpha06"
4251

4352
testImplementation 'junit:junit:4.12'
4453
testImplementation 'androidx.test:runner:1.3.0'
@@ -72,7 +81,7 @@ ext {
7281
siteUrl = 'https://github.com/Iterable/iterable-android-sdk'
7382
gitUrl = 'https://github.com/Iterable/iterable-android-sdk.git'
7483

75-
libraryVersion = '3.4.9'
84+
libraryVersion = '3.4.16'
7685

7786
developerId = 'davidtruong'
7887
developerName = 'David Truong'
@@ -84,12 +93,14 @@ ext {
8493
}
8594

8695
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
87-
if(hasProperty("mavenPublishEnabled")) {
96+
97+
if (hasProperty("mavenPublishEnabled")) {
8898
apply from: '../maven-push.gradle'
8999
}
90100

91101
task javadoc(type: Javadoc) {
92102
source = android.sourceSets.main.java.srcDirs
103+
excludes = ['**/*.kt']
93104
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
94105

95106
exclude '**/*.kt'
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:tools="http://schemas.android.com/tools"
3-
xmlns:android="http://schemas.android.com/apk/res/android"
4-
package="iterable.com.iterableapi">
5-
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator"/>
2+
<manifest xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" package="iterable.com.iterableapi">
3+
<uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator,androidx.security"/>
64
<application
75
android:label="IterableAPI"
8-
android:supportsRtl="true"/>
6+
android:supportsRtl="true" />
97
</manifest>

0 commit comments

Comments
 (0)