/*
* Copyright (C) 2014 Jason M. Heim
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jasonmheim.rollout.sync;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import com.google.gson.Gson;
import com.jasonmheim.rollout.Constants;
import com.jasonmheim.rollout.data.StationList;
import com.squareup.otto.Bus;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Helper class to manage the last known station list. This downloads the data from the content
* provider but also registers a {@link ContentObserver} so that any updates to data, location, or
* action will trigger the data to be re-obtained and broadcast within the process.
*/
@Singleton
public class LastKnownStationList {
private final Bus bus;
private final Gson gson;
private final ContentResolver contentResolver;
private StationList stationList;
@Inject
public LastKnownStationList(
Bus bus,
ContentResolver contentResolver,
Gson gson) {
this.bus = bus;
this.contentResolver = contentResolver;
this.gson = gson;
}
public synchronized StationList get() {
if (stationList == null) {
Cursor cursor = contentResolver.query(Constants.STATION_URI, null, null, null, null);
try {
// TODO: make a helper for serialization/deserialization
stationList = gson.fromJson(cursor.getString(0), StationList.class);
contentResolver.registerContentObserver(Constants.STATION_URI, true, new Observer());
Log.i("Rollout", "Initialized last know station list.");
} catch (RuntimeException ex) {
Log.w("Rollout", "Failed to deserialize station list during initialization.", ex);
} finally {
cursor.close();
}
}
return stationList;
}
/**
* Observer for changes to station list data.
*/
private class Observer extends ContentObserver {
// TODO: just make the outer class the content observer?
public Observer() {
super(new Handler());
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
Cursor cursor = contentResolver.query(Constants.STATION_URI, null, null, null, null);
try {
stationList = gson.fromJson(cursor.getString(0), StationList.class);
Log.i("Rollout", "Content observer received update.");
bus.post(new StationDataUpdateEvent(stationList));
} catch (RuntimeException ex) {
Log.w("Rollout", "Failed to deserialize station list from update.", ex);
} finally {
cursor.close();
}
}
}
}