3333import android .graphics .drawable .shapes .Shape ;
3434import android .os .Build ;
3535import android .os .Handler ;
36+ import android .text .Layout ;
3637import android .text .TextUtils ;
3738import android .util .TypedValue ;
3839import android .view .Gravity ;
3940import android .view .MotionEvent ;
4041import android .view .View ;
42+ import android .view .ViewGroup ;
4143import android .view .ViewGroup .LayoutParams ;
4244import android .view .Window ;
4345import android .view .WindowManager ;
5658import com .leanplum .ActionContext ;
5759import com .leanplum .Leanplum ;
5860import com .leanplum .core .R ;
61+ import com .leanplum .internal .Log ;
5962import com .leanplum .utils .BitmapUtil ;
6063import com .leanplum .utils .SizeUtil ;
6164import com .leanplum .views .BackgroundImageView ;
@@ -113,7 +116,6 @@ protected BaseMessageDialog(Activity activity, boolean fullscreen, BaseMessageOp
113116 CloseButton closeButton = createCloseButton (activity , fullscreen , view );
114117 dialogView .addView (closeButton , closeButton .getLayoutParams ());
115118 }
116-
117119 setContentView (dialogView , dialogView .getLayoutParams ());
118120
119121 dialogView .setAnimation (createFadeInAnimation ());
@@ -130,16 +132,51 @@ protected BaseMessageDialog(Activity activity, boolean fullscreen, BaseMessageOp
130132 }
131133 } else {
132134 window .clearFlags (WindowManager .LayoutParams .FLAG_DIM_BEHIND );
133- window .setFlags (WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL ,
134- WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL );
135+
136+ if (htmlOptions != null && isBannerWithTapOutsideFalse (htmlOptions )) {
137+ // banners need to be positioned at the top manually
138+ // (unless they get repositioned to the bottom later)
139+ window .setLayout (LayoutParams .MATCH_PARENT , LayoutParams .WRAP_CONTENT );
140+ window .setGravity (Gravity .TOP );
141+
142+ // use the html y offset to determine the y location of the window; this is different
143+ // from non-banners because we don't want to make the window too big (e.g. via a margin
144+ // in the layout) and block other things on the screen (e.g. dialogs)
145+ WindowManager .LayoutParams windowLayoutParams = window .getAttributes ();
146+ windowLayoutParams .y = htmlOptions .getHtmlYOffset (activity );
147+ window .setAttributes (windowLayoutParams );
148+
149+ window .setFlags (WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL | WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE ,
150+ WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL | WindowManager .LayoutParams .FLAG_NOT_FOCUSABLE );
151+ } else {
152+ window .setFlags (WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL ,
153+ WindowManager .LayoutParams .FLAG_NOT_TOUCH_MODAL );
154+ }
155+
135156 if (htmlOptions != null &&
136157 MessageTemplates .Args .HTML_ALIGN_BOTTOM .equals (htmlOptions .getHtmlAlign ())) {
137- dialogView .setGravity (Gravity .BOTTOM );
158+ if (isBannerWithTapOutsideFalse (htmlOptions )) {
159+ window .setGravity (Gravity .BOTTOM );
160+ } else {
161+ dialogView .setGravity (Gravity .BOTTOM );
162+ }
138163 }
139164 }
140165 }
141166 }
142167
168+ /**
169+ * Banners with property TabOutsideToClose = false need to be treated differently
170+ * so they do not block interaction with other dialogs and the keyboard.
171+ * Banners with property TabOutsideToClose = true do not need to be treated this way.
172+ * The original way banners worked was fine because they need to be aware of any touch events
173+ * in its container window
174+ */
175+ protected static boolean isBannerWithTapOutsideFalse (HTMLOptions htmlOptions ) {
176+ String templateName = htmlOptions .getActionContext ().getArgs ().get ("__file__Template" ).toString ();
177+ return templateName .toLowerCase ().contains ("banner" ) && !htmlOptions .isHtmlTabOutsideToClose ();
178+ }
179+
143180 @ Override
144181 public void onWindowFocusChanged (boolean hasFocus ) {
145182 try {
@@ -260,10 +297,12 @@ private RelativeLayout createContainerView(Activity context, boolean fullscreen)
260297
261298 layoutParams .addRule (RelativeLayout .CENTER_HORIZONTAL , RelativeLayout .TRUE );
262299 int htmlYOffset = htmlOptions .getHtmlYOffset (context );
263- if (MessageTemplates .Args .HTML_ALIGN_BOTTOM .equals (htmlOptions .getHtmlAlign ())) {
264- layoutParams .bottomMargin = htmlYOffset ;
265- } else {
266- layoutParams .topMargin = htmlYOffset ;
300+ if (!isBannerWithTapOutsideFalse (htmlOptions )) {
301+ if (MessageTemplates .Args .HTML_ALIGN_BOTTOM .equals (htmlOptions .getHtmlAlign ())) {
302+ layoutParams .bottomMargin = htmlYOffset ;
303+ } else {
304+ layoutParams .topMargin = htmlYOffset ;
305+ }
267306 }
268307 } else {
269308 // Make sure the dialog fits on screen.
0 commit comments