Skip to content

Commit

Permalink
Merge pull request #77 in MML/infobip-mobile-messaging-android from M…
Browse files Browse the repository at this point in the history
…M-1337-Geo_areas_with_campaignId to master

Squashed commit of the following:

commit 9d6afbd5d18d7cab56ad3b5b187a2fde9d4d3c88
Author: tjuric <[email protected]>
Date:   Tue Feb 28 21:14:30 2017 +0100

    MM-1337 - Geo areas are being monitored by campaign ID - bugfixes

commit 1108cb324b94bcf65ae68bcf10eb237eb2473163
Author: tjuric <[email protected]>
Date:   Tue Feb 28 16:56:25 2017 +0100

    MM-1337 - Geo areas are being monitored by campaign ID
  • Loading branch information
tjuric committed Mar 1, 2017
1 parent d679629 commit 0497ae9
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.mockito.Mockito;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
Expand Down Expand Up @@ -69,7 +70,7 @@ protected void tearDown() throws Exception {
super.tearDown();
}

public void test_shoudProvide_MESSAGE_RECEIVED_forGeoTransition() throws Exception {
public void test_shouldProvide_MESSAGE_RECEIVED_forGeoTransition() throws Exception {

// Given
final Area area = new Area("areaId", "", 1.0, 2.0, 3);
Expand Down Expand Up @@ -100,4 +101,25 @@ public String getRequestId() {
assertEquals("campaignId", message.getGeo().getCampaignId());
assertEquals("areaId", message.getGeo().getAreasList().get(0).getId());
}

public void test_shouldCompareRadiusInGeoAreasList() {
final Area area1 = new Area("areaId1", "", 1.0, 2.0, 700);
final Area area2 = new Area("areaId2", "", 1.0, 2.0, 250);
final Area area3 = new Area("areaId3", "", 1.0, 2.0, 1000);
List<Area> areasList = new ArrayList<Area>() {{
add(area1);
add(area2);
add(area3);
}};

GeoAreasHandler.GeoAreaRadiusComparator geoAreaRadiusComparator = new GeoAreasHandler.GeoAreaRadiusComparator();
Collections.sort(areasList, geoAreaRadiusComparator);

assertEquals(areasList.get(0).getId(), area2.getId());
assertEquals(areasList.get(0).getRadius(), area2.getRadius());
assertEquals(areasList.get(1).getId(), area1.getId());
assertEquals(areasList.get(1).getRadius(), area1.getRadius());
assertEquals(areasList.get(2).getId(), area3.getId());
assertEquals(areasList.get(2).getRadius(), area3.getRadius());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -91,23 +94,24 @@ void handleTransition(Intent intent) {

void handleTransition(List<Geofence> triggeringGeofences, int geofenceTransition, Location triggeringLocation) {

Map<Message, List<Area>> messagesAndAreas = findMessagesAndAreasForTriggeringGeofences(
context, triggeringGeofences);
if (messagesAndAreas == null || messagesAndAreas.isEmpty()) {
Map<Message, List<Area>> messagesAndAreas = findActiveMessagesAndAreasForTriggeredGeofences(context, triggeringGeofences);
Map<Message, List<Area>> filteredMessagesAndAreas = filterOverlappingAreas(messagesAndAreas);

if (filteredMessagesAndAreas == null || filteredMessagesAndAreas.isEmpty()) {
return;
}

ArrayList<GeoReport> geoReports = new ArrayList<>();
ArrayList<Pair<Geo, Message>> geoDataToNotify = new ArrayList<>();
ArrayList<GeoReport> geoReports = new ArrayList<>(filteredMessagesAndAreas.size());
ArrayList<Pair<Geo, Message>> geoDataToNotify = new ArrayList<>(filteredMessagesAndAreas.size());

for (Message message : messagesAndAreas.keySet()) {
for (Message message : filteredMessagesAndAreas.keySet()) {

List<Area> geofenceAreasList = messagesAndAreas.get(message);
List<Area> geofenceAreasList = filteredMessagesAndAreas.get(message);
logGeofences(geofenceAreasList, geofenceTransition);

for (final Area area : geofenceAreasList) {

if (!shouldReportTransition(message, area, geofenceTransition)) {
if (!shouldReportTransition(message, geofenceTransition)) {
continue;
}

Expand Down Expand Up @@ -162,19 +166,17 @@ private void displayNotificationsForActiveCampaigns(ArrayList<Pair<Geo, Message>
continue;
}

for (Area area : geo.getAreasList()) {
setLastNotificationTimeForArea(message.getMessageId(), area.getId(), geofenceTransition, System.currentTimeMillis());
setNumberOfDisplayedNotificationsForArea(message.getMessageId(), area.getId(), geofenceTransition,
getNumberOfDisplayedNotificationsForArea(message.getMessageId(), area.getId(), geofenceTransition) + 1);
}
setLastNotificationTimeForArea(message.getGeo().getCampaignId(), geofenceTransition, System.currentTimeMillis());
setNumberOfDisplayedNotificationsForArea(message.getGeo().getCampaignId(), geofenceTransition,
getNumberOfDisplayedNotificationsForArea(message.getGeo().getCampaignId(), geofenceTransition) + 1);

notifyAboutTransition(context, geo, geofenceTransition, geoData.second);
}
}

private boolean shouldReportTransition(Message message, Area area, int geofenceTransition) {
int numberOfDisplayedNotifications = getNumberOfDisplayedNotificationsForArea(message.getMessageId(), area.getId(), geofenceTransition);
long lastNotificationTimeForArea = getLastNotificationTimeForArea(message.getMessageId(), area.getId(), geofenceTransition);
private boolean shouldReportTransition(Message message, int geofenceTransition) {
int numberOfDisplayedNotifications = getNumberOfDisplayedNotificationsForArea(message.getGeo().getCampaignId(), geofenceTransition);
long lastNotificationTimeForArea = getLastNotificationTimeForArea(message.getGeo().getCampaignId(), geofenceTransition);
Geo geo = message.getGeo();
GeoEvent settings = getNotificationSettingsForTransition(geo.getEvents(), geofenceTransition);

Expand Down Expand Up @@ -262,32 +264,32 @@ private GeoEvent getNotificationSettingsForTransition(List<GeoEvent> eventFilter
return null;
}

private String areaNotificationNumKey(String messageId, String areaId, int geofenceTransition) {
return AREA_NOTIFIED_PREF_PREFIX + messageId + "-" + areaId + "-" + geofenceTransition;
private String areaNotificationNumKey(String campaignId, int geofenceTransition) {
return AREA_NOTIFIED_PREF_PREFIX + campaignId + "-" + geofenceTransition;
}

private String areaNotificationTimeKey(String messageId, String areaId, int geofenceTransition) {
return AREA_LAST_TIME_PREF_PREFIX + messageId + "-" + areaId + "-" + geofenceTransition;
private String areaNotificationTimeKey(String campaignId, int geofenceTransition) {
return AREA_LAST_TIME_PREF_PREFIX + campaignId + "-" + geofenceTransition;
}

private boolean geoEventMatchesTransition(GeoEvent event, int geofenceTransition) {
return event.getType().equals(DEFAULT_NOTIFICATION_SETTINGS_FOR_ENTER.getType()) && geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER;
}

private int getNumberOfDisplayedNotificationsForArea(String messageId, String areaId, int geofenceTransition) {
return PreferenceHelper.findInt(context, areaNotificationNumKey(messageId, areaId, geofenceTransition), 0);
private int getNumberOfDisplayedNotificationsForArea(String campaignId, int geofenceTransition) {
return PreferenceHelper.findInt(context, areaNotificationNumKey(campaignId, geofenceTransition), 0);
}

private void setNumberOfDisplayedNotificationsForArea(String messageId, String areaId, int geofenceTransition, int n) {
PreferenceHelper.saveInt(context, areaNotificationNumKey(messageId, areaId, geofenceTransition), n);
private void setNumberOfDisplayedNotificationsForArea(String campaignId, int geofenceTransition, int n) {
PreferenceHelper.saveInt(context, areaNotificationNumKey(campaignId, geofenceTransition), n);
}

private long getLastNotificationTimeForArea(String messageId, String areaId, int geofenceTransition) {
return PreferenceHelper.findLong(context, areaNotificationTimeKey(messageId, areaId, geofenceTransition), 0);
private long getLastNotificationTimeForArea(String campaignId, int geofenceTransition) {
return PreferenceHelper.findLong(context, areaNotificationTimeKey(campaignId, geofenceTransition), 0);
}

private void setLastNotificationTimeForArea(String messageId, String areaId, int geofenceTransition, long timeMs) {
PreferenceHelper.saveLong(context, areaNotificationTimeKey(messageId, areaId, geofenceTransition), timeMs);
private void setLastNotificationTimeForArea(String campaignId, int geofenceTransition, long timeMs) {
PreferenceHelper.saveLong(context, areaNotificationTimeKey(campaignId, geofenceTransition), timeMs);
}

private void notifyAboutTransition(Context context, Geo geo, int geofenceTransition, Message message) {
Expand Down Expand Up @@ -331,14 +333,23 @@ private void logGeofences(List<Area> areas, int transition) {
}
}

private Map<Message, List<Area>> findMessagesAndAreasForTriggeringGeofences(Context context, List<Geofence> geofences) {
private Map<Message, List<Area>> findActiveMessagesAndAreasForTriggeredGeofences(Context context, List<Geofence> geofences) {
Date now = new Date();
Map<Message, List<Area>> messagesAndAreas = new HashMap<>();

for (Message message : messageStore.findAll(context)) {
Geo geo = message.getGeo();

if (geo == null || geo.getAreasList() == null || geo.getAreasList().isEmpty()) {
continue;
}

//don't trigger geo event before start date
Date startDate = geo.getStartDate();
if (startDate != null && startDate.after(now)) {
continue;
}

List<Area> campaignAreas = geo.getAreasList();
List<Area> triggeredAreas = new ArrayList<>();
for (Area area : campaignAreas) {
Expand All @@ -356,4 +367,30 @@ private Map<Message, List<Area>> findMessagesAndAreasForTriggeringGeofences(Cont

return messagesAndAreas;
}

private Map<Message, List<Area>> filterOverlappingAreas(Map<Message, List<Area>> messagesAndAreas) {
Map<Message, List<Area>> filteredMessagesAndAreas = new HashMap<>(messagesAndAreas.size());

for (Message message : messagesAndAreas.keySet()) {
List<Area> areasList = message.getGeo().getAreasList();

if (areasList != null) {
//using only area that has the smallest radius
Collections.sort(areasList, new GeoAreaRadiusComparator());
filteredMessagesAndAreas.put(message, Collections.singletonList(areasList.get(0)));
}
}

return filteredMessagesAndAreas;
}


static class GeoAreaRadiusComparator implements Comparator<Area> {

@Override
public int compare(Area area1, Area area2) {
return area1.getRadius() - area2.getRadius();
}
}

}

0 comments on commit 0497ae9

Please sign in to comment.