Skip to content

Commit

Permalink
Add observers for event trigger count for each event
Browse files Browse the repository at this point in the history
- need to measure the cost of LiveData per event
- remove the `modifyPos` logic
- remove redundant calls to notify data change for adapter
- remove book-keeping work on event list and let observer callback
  handle the list
- refactor field names to remove hungarian notation

Signed-off-by: Arka Prava Basu <[email protected]>
  • Loading branch information
archie94 committed Nov 7, 2018
1 parent 0293988 commit 6f96605
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ class RoomMigrationTest {
val event = migratedDb.getEventDAO().getAllEvent()[0]
val eventTrigger = migratedDb.getEventTriggerDAO().getAllEventTriggers()[0]

assertEquals(dateToTimestamp(event.mStartTime)?.toInt(), 123)
assertEquals(dateToTimestamp(event.startTime)?.toInt(), 123)

assertEquals(dateToTimestamp(eventTrigger.mTime)?.toInt(), 124)
assertEquals(eventTrigger.mPath, "abcabd")
assertEquals(eventTrigger.mType, 1)
assertEquals(dateToTimestamp(eventTrigger.time)?.toInt(), 124)
assertEquals(eventTrigger.path, "abcabd")
assertEquals(eventTrigger.type, 1)
}

@After
Expand Down
79 changes: 31 additions & 48 deletions src/main/java/org/havenapp/main/ListActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package org.havenapp.main;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
Expand Down Expand Up @@ -66,12 +65,12 @@
import org.havenapp.main.ui.EventAdapter;
import org.havenapp.main.ui.PPAppIntro;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import kotlin.Pair;

import static org.havenapp.main.database.DbConstantsKt.DB_INIT_END;
import static org.havenapp.main.database.DbConstantsKt.DB_INIT_START;
import static org.havenapp.main.database.DbConstantsKt.DB_INIT_STATUS;
Expand All @@ -86,27 +85,40 @@ public class ListActivity extends AppCompatActivity {
private PreferenceManager preferences;
private IResourceManager resourceManager;

private int modifyPos = -1;

private int REQUEST_CODE_INTRO = 1001;

private LiveData<List<Event>> eventListLD;

private Observer<List<Event>> eventListObserver = events -> {
if (events != null) {
setEventListToRecyclerView(events);
observeEvents(events);
}
};

private Observer<Integer> eventCountObserver = count -> {
if (count != null && count > events.size()) {
fetchEventList();
showNonEmptyState();
} else if (count != null && count == 0) {
showEmptyState();
}
};

private Observer<Pair<Long, Integer>> eventTriggerCountObserver = pair -> {
if (pair != null && adapter != null && events != null) {
int pos = -1;
for (int i = 0; i < events.size(); i++) {
if (events.get(i).getId().equals(pair.getFirst())) {
pos = i;
break;
}
}
if (pos != -1) {
adapter.notifyItemChanged(pos);
}
}
};

private BroadcastReceiver dbBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Expand Down Expand Up @@ -144,9 +156,6 @@ protected void onCreate(Bundle savedInstanceState) {
LinearLayoutManager llm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(llm);

if (savedInstanceState != null)
modifyPos = savedInstanceState.getInt("modify");


// Handling swipe to delete
ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
Expand All @@ -160,12 +169,8 @@ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHol
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//Remove swiped item from list and notify the RecyclerView

final int position = viewHolder.getAdapterPosition();
final Event event = events.get(viewHolder.getAdapterPosition());

deleteEvent(event, position);


deleteEvent(event);
}

};
Expand Down Expand Up @@ -212,7 +217,6 @@ private void initializeRecyclerViewComponents() {

Intent i = new Intent(ListActivity.this, EventActivity.class);
i.putExtra("eventid", events.get(position).getId());
modifyPos = position;

startActivity(i);
});
Expand All @@ -228,6 +232,14 @@ private void setEventListToRecyclerView(@NonNull List<Event> events) {
adapter.setEvents(events);
}

private void observeEvents(@NonNull List<Event> events) {
for (Event event: events) {
if (event.getEventTriggersCountLD() == null)
continue;
event.getEventTriggersCountLD().observe(this, eventTriggerCountObserver);
}
}

private void fetchEventList() {
try {
eventListLD = HavenEventDB.getDatabase(this).getEventDAO().getAllEventDesc();
Expand All @@ -247,14 +259,12 @@ private void showNonEmptyState() {
findViewById(R.id.empty_view).setVisibility(View.GONE);
}

private void deleteEvent (final Event event, final int position)
private void deleteEvent(final Event event)
{
new EventDeleteAsync(() -> onEventDeleted(event, position)).execute(event);
events.remove(position);
adapter.notifyItemRemoved(position);
new EventDeleteAsync(() -> onEventDeleted(event)).execute(event);
}

private void onEventDeleted(Event event, int position) {
private void onEventDeleted(Event event) {
Snackbar.make(recyclerView, resourceManager.getString(R.string.event_deleted), Snackbar.LENGTH_SHORT)
.setAction(resourceManager.getString(R.string.undo),
v -> new EventInsertAsync(eventId -> {
Expand All @@ -275,36 +285,11 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

outState.putInt("modify", modifyPos);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);

modifyPos = savedInstanceState.getInt("modify");
}

@Override
protected void onResume() {
super.onResume();

resourceManager = new ResourceManager(this);
HavenEventDB.getDatabase(this).getEventDAO().count().observe(this, eventCountObserver);

if (modifyPos != -1) {
//Event.set(modifyPos, Event.listAll(Event.class).get(modifyPos));
adapter.notifyItemChanged(modifyPos);
}
}

@SuppressLint("SimpleDateFormat")
public static String getDateFormat(long date) {
return new SimpleDateFormat("dd MMM yyyy").format(new Date(date));
}

private void showOnboarding()
Expand Down Expand Up @@ -350,9 +335,7 @@ protected void onDestroy() {

private void removeAllEvents()
{
final List<Event> removedEvents = new ArrayList<Event>(events);
events.clear();
adapter.notifyDataSetChanged();
final List<Event> removedEvents = new ArrayList<>(events);
new EventDeleteAllAsync(() -> onAllEventsRemoved(removedEvents)).execute(removedEvents);
}

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/havenapp/main/PreferenceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,11 @@ public int getHeartbeatNotificationTimeMs () {
}

/**
* Set the {@link org.havenapp.main.model.Event#mStartTime} for the ongoing event.
* Set the {@link org.havenapp.main.model.Event#startTime} for the ongoing event.
* Sets a string with the format {@link Utils#DATE_TIME_PATTERN}
* representing current date and time for the key {@link #CURRENT_EVENT_START_TIME}.
*
* @param startTime the {@link org.havenapp.main.model.Event#mStartTime} for an
* @param startTime the {@link org.havenapp.main.model.Event#startTime} for an
* {@link org.havenapp.main.model.Event}
*/
public void setCurrentSession(Date startTime) {
Expand All @@ -364,7 +364,7 @@ public void setCurrentSession(Date startTime) {
}

/**
* Get the {@link org.havenapp.main.model.Event#mStartTime} for the ongoing event.
* Get the {@link org.havenapp.main.model.Event#startTime} for the ongoing event.
*
* @return the string corresponding to pref key {@link #CURRENT_EVENT_START_TIME}.
* Default value is unknown_session.
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/havenapp/main/dao/EventTriggerDAO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ interface EventTriggerDAO {
fun getEventTriggerListAsync(eventId: Long?) : LiveData<MutableList<EventTrigger>>

@Query("SELECT * FROM EVENT_TRIGGER")
fun getAllEventTriggers() : MutableList<EventTrigger> // todo remove this for now
fun getAllEventTriggers() : MutableList<EventTrigger>

@Query("SELECT COUNT(*) FROM EVENT_TRIGGER WHERE M_EVENT_ID = :eventId")
fun getEventTriggerListCountAsync(eventId: Long?) : LiveData<Int>
}
42 changes: 27 additions & 15 deletions src/main/java/org/havenapp/main/model/Event.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.havenapp.main.model

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.Transformations
import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.Ignore
Expand All @@ -16,39 +18,49 @@ class Event {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "ID")
var id : Long? = null
get() = field
set(value) {
if (value == null) return
field = value
eventTriggerCountLD = Transformations.map(HavenApp.getDataBaseInstance().getEventTriggerDAO()
.getEventTriggerListCountAsync(field)) {
Pair(field!!, it)
}
}

@ColumnInfo(name = "M_START_TIME")
var mStartTime : Date? = Date()
var startTime : Date? = Date()

@Ignore
private var eventTriggers : MutableList<EventTrigger> = mutableListOf()

@Ignore
private var mEventTriggers : MutableList<EventTrigger> = mutableListOf()
private var eventTriggerCountLD: LiveData<Pair<Long, Int>>? = null

fun addEventTrigger(eventTrigger: EventTrigger) {
mEventTriggers.add(eventTrigger)
eventTrigger.mEventId = id
eventTriggers.add(eventTrigger)
eventTrigger.eventId = id
}

/**
* Get the list of event triggers associated with this event.
* <p>
* When [mEventTriggers] is empty this method performs a blocking db lookup.
* When [eventTriggers] is empty this method performs a blocking db lookup.
*/
fun getEventTriggers() : MutableList<EventTrigger> {

if (mEventTriggers.size == 0) {
if (eventTriggers.size == 0) {
val eventTriggers = HavenApp.getDataBaseInstance().getEventTriggerDAO().getEventTriggerList(id)
mEventTriggers.addAll(eventTriggers)
this.eventTriggers.addAll(eventTriggers)
}

return mEventTriggers
return eventTriggers
}

fun getEventTriggerCount(): Int {
if (mEventTriggers.size == 0) {
return getEventTriggers().size
}
fun getEventTriggersCountLD(): LiveData<Pair<Long, Int>>? {
return eventTriggerCountLD
}

return mEventTriggers.size
fun getEventTriggerCount(): Int {
return eventTriggerCountLD?.value?.second ?: 0
}
}
}
15 changes: 7 additions & 8 deletions src/main/java/org/havenapp/main/model/EventTrigger.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,24 @@ class EventTrigger {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "ID")
var id : Long? = null
get() = field

@ColumnInfo(name = "M_TYPE")
var mType: Int? = 0
var type: Int? = 0

// Trigger time
@ColumnInfo(name = "M_TIME")
var mTime: Date? = Date()
var time: Date? = Date()

@ColumnInfo(name = "M_EVENT_ID")
var mEventId: Long? = 0
var eventId: Long? = 0

@ColumnInfo(name = "M_PATH")
var mPath: String? = null
var path: String? = null

fun getStringType(resourceManager: IResourceManager): String {
var sType = ""

sType = when (mType) {
sType = when (type) {
ACCELEROMETER -> resourceManager.getString(R.string.sensor_accel)
LIGHT -> resourceManager.getString(R.string.sensor_light)
CAMERA -> resourceManager.getString(R.string.sensor_camera)
Expand All @@ -98,7 +97,7 @@ class EventTrigger {
fun getMimeType(): String? {
var mimeType: String? = ""

mimeType = when (mType) {
mimeType = when (type) {
CAMERA -> "image/*"
MICROPHONE -> "audio/*"
CAMERA_VIDEO -> "video/*"
Expand All @@ -107,4 +106,4 @@ class EventTrigger {

return mimeType
}
}
}
18 changes: 9 additions & 9 deletions src/main/java/org/havenapp/main/service/MonitorService.java
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ public synchronized void alert(int alertType, String path) {
mLastEvent.setId(eventId);
doNotification = true;
// set current event start date in prefs
mPrefs.setCurrentSession(mLastEvent.getMStartTime());
mPrefs.setCurrentSession(mLastEvent.getStartTime());
}
else if (mPrefs.getNotificationTimeMs() == 0)
{
Expand All @@ -318,8 +318,8 @@ else if (mPrefs.getNotificationTimeMs() > 0 && mLastNotification != null)
}

EventTrigger eventTrigger = new EventTrigger();
eventTrigger.setMType(alertType);
eventTrigger.setMPath(path);
eventTrigger.setType(alertType);
eventTrigger.setPath(path);

mLastEvent.addEventTrigger(eventTrigger);

Expand Down Expand Up @@ -353,13 +353,13 @@ else if (mPrefs.getNotificationTimeMs() > 0 && mLastNotification != null)
recips.add(st.nextToken());

String attachment = null;
if (eventTrigger.getMType() == EventTrigger.CAMERA) {
attachment = eventTrigger.getMPath();
} else if (eventTrigger.getMType() == EventTrigger.MICROPHONE) {
attachment = eventTrigger.getMPath();
if (eventTrigger.getType() == EventTrigger.CAMERA) {
attachment = eventTrigger.getPath();
} else if (eventTrigger.getType() == EventTrigger.MICROPHONE) {
attachment = eventTrigger.getPath();
}
else if (eventTrigger.getMType() == EventTrigger.CAMERA_VIDEO) {
attachment = eventTrigger.getMPath();
else if (eventTrigger.getType() == EventTrigger.CAMERA_VIDEO) {
attachment = eventTrigger.getPath();
}

sender.sendMessage(recips, alertMessage.toString(), attachment);
Expand Down
Loading

0 comments on commit 6f96605

Please sign in to comment.