Skip to content

Commit 53c6761

Browse files
committed
Add DialogFragment detection and improvement on system detection
* Not show IAM if an DialogFragment is visible * Queue IAM even if systems conditions aren't correct * Reevaluate condition and display IAM after systems condition changed, no need for triggers evaluation
1 parent 4e989f5 commit 53c6761

File tree

4 files changed

+77
-9
lines changed

4 files changed

+77
-9
lines changed

OneSignalSDK/onesignal/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ dependencies {
6363
api 'com.android.support:cardview-v7:[26.0.0, 27.99.99]'
6464
api 'com.android.support:support-v4:[26.0.0, 27.99.99]'
6565
api 'com.android.support:customtabs:[26.0.0, 27.99.99]'
66+
api 'com.android.support:appcompat-v7:[26.0.0, 27.99.99]'
6667
}
6768

6869
apply from: 'maven-push.gradle'

OneSignalSDK/onesignal/src/main/java/com/onesignal/ActivityLifecycleHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public void onGlobalLayout() {
288288
}
289289
}
290290
ActivityLifecycleHandler.removeSystemConditionObserver(key);
291-
observer.messageTriggerConditionChanged();
291+
observer.systemConditionChanged();
292292
}
293293
}
294294
}

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSInAppMessageController.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,10 @@ public void run() {
187187
}
188188

189189
private void evaluateInAppMessages() {
190-
if (systemConditionController.systemConditionsAvailable()) {
191-
for (OSInAppMessage message : messages) {
192-
setDataForRedisplay(message);
193-
if (!dismissedMessages.contains(message.messageId) && triggerController.evaluateMessageTriggers(message))
194-
queueMessageForDisplay(message);
195-
}
190+
for (OSInAppMessage message : messages) {
191+
setDataForRedisplay(message);
192+
if (!dismissedMessages.contains(message.messageId) && triggerController.evaluateMessageTriggers(message))
193+
queueMessageForDisplay(message);
196194
}
197195
}
198196

@@ -485,7 +483,19 @@ private void queueMessageForDisplay(@NonNull OSInAppMessage message) {
485483
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "In app message with id, " + message.messageId + ", added to the queue");
486484
}
487485

488-
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "queueMessageForDisplay: " + messageDisplayQueue);
486+
attemptToShowInAppMessage();
487+
}
488+
}
489+
490+
private void attemptToShowInAppMessage() {
491+
synchronized (messageDisplayQueue) {
492+
// We need to wait for system conditions to be the correct ones
493+
if (!systemConditionController.systemConditionsAvailable()) {
494+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.WARN, "In app message not showing due to system condition not correct");
495+
return;
496+
}
497+
498+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "displayFirstIAMOnQueue: " + messageDisplayQueue);
489499
// If there are IAMs in the queue and nothing showing, show first in the queue
490500
if (messageDisplayQueue.size() > 0 && !isInAppMessageShowing()) {
491501
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.DEBUG, "No IAM showing currently, showing first item in the queue!");
@@ -691,6 +701,17 @@ public void messageTriggerConditionChanged() {
691701
evaluateInAppMessages();
692702
}
693703

704+
/**
705+
* If this method is called a system condition has changed to success
706+
* - Keyboard is down
707+
* - No DialogFragment visible
708+
* - Activity is on focus, this mean no prompt permissions visible
709+
*/
710+
@Override
711+
public void systemConditionChanged() {
712+
attemptToShowInAppMessage();
713+
}
714+
694715
/**
695716
* Part of redisplay logic
696717
*

OneSignalSDK/onesignal/src/main/java/com/onesignal/OSSystemConditionController.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
package com.onesignal;
22

3+
import android.content.Context;
4+
import android.support.annotation.NonNull;
5+
import android.support.v4.app.DialogFragment;
6+
import android.support.v4.app.Fragment;
7+
import android.support.v4.app.FragmentManager;
8+
import android.support.v7.app.AppCompatActivity;
9+
310
import java.lang.ref.WeakReference;
11+
import java.util.List;
412

513
class OSSystemConditionController {
614

715
interface OSSystemConditionObserver {
816
// Alerts the systemConditionObserver that a system condition has being activated
9-
void messageTriggerConditionChanged();
17+
void systemConditionChanged();
1018
}
1119

1220
private static final String TAG = OSSystemConditionController.class.getCanonicalName();
@@ -18,13 +26,51 @@ interface OSSystemConditionObserver {
1826

1927
boolean systemConditionsAvailable() {
2028
if (ActivityLifecycleHandler.curActivity == null) {
29+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.WARN, "OSSystemConditionObserver curActivity null");
2130
return false;
2231
}
32+
33+
if (isDialogFragmentShowing(ActivityLifecycleHandler.curActivity)) {
34+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.WARN, "OSSystemConditionObserver dialog fragment detected");
35+
return false;
36+
}
37+
2338
boolean keyboardUp = OSViewUtils.isKeyboardUp(new WeakReference<>(ActivityLifecycleHandler.curActivity));
2439
if (keyboardUp) {
2540
ActivityLifecycleHandler.setSystemConditionObserver(TAG, systemConditionObserver);
41+
OneSignal.onesignalLog(OneSignal.LOG_LEVEL.WARN, "OSSystemConditionObserver keyboard up detected");
2642
}
2743
return !keyboardUp;
2844
}
2945

46+
boolean isDialogFragmentShowing(Context context) {
47+
// Detect if user has a dialog fragment showing
48+
if (context instanceof AppCompatActivity) {
49+
final FragmentManager manager = ((AppCompatActivity) context).getSupportFragmentManager();
50+
manager.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {
51+
52+
@Override
53+
public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment fragmentDetached) {
54+
super.onFragmentDetached(fm, fragmentDetached);
55+
if (fragmentDetached instanceof DialogFragment) {
56+
manager.unregisterFragmentLifecycleCallbacks(this);
57+
systemConditionObserver.systemConditionChanged();
58+
}
59+
}
60+
61+
}, true);
62+
List<Fragment> fragments = manager.getFragments();
63+
int size = fragments.size();
64+
if (size > 0) {
65+
// We only care of the last fragment available
66+
Fragment fragment = fragments.get(size - 1);
67+
return fragment.isVisible() && fragment instanceof DialogFragment;
68+
}
69+
}
70+
71+
// We already have Activity lifecycle listener, that listener will handle Activity focus/unFocus state
72+
// - Permission prompts will make activity loose focus
73+
// We cannot detect AlertDialogs because they are added to the decor view as linear layout without an identification
74+
return false;
75+
}
3076
}

0 commit comments

Comments
 (0)