Java tutorial
/** * This file is part of MythTV Android Frontend * * MythTV Android Frontend is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MythTV Android Frontend is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MythTV Android Frontend. If not, see <http://www.gnu.org/licenses/>. * * This software can be found at <https://github.com/MythTV-Clients/MythTV-Android-Frontend/> */ /** * */ package org.mythtv.service.content.v25; import java.util.ArrayList; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.mythtv.client.ui.preferences.LocationProfile; import org.mythtv.client.ui.preferences.LocationProfile.LocationType; import org.mythtv.client.ui.preferences.PlaybackProfile; import org.mythtv.db.AbstractBaseHelper; import org.mythtv.db.content.LiveStreamConstants; import org.mythtv.db.http.model.EtagInfoDelegate; import org.mythtv.db.preferences.PlaybackProfileDaoHelper; import org.mythtv.service.content.LiveStreamService; import org.mythtv.service.dvr.v25.RecordedHelperV25; import org.mythtv.service.util.NetworkHelper; import org.mythtv.services.api.ApiVersion; import org.mythtv.services.api.Bool; import org.mythtv.services.api.ETagInfo; import org.mythtv.services.api.connect.MythAccessFactory; import org.mythtv.services.api.v025.MythServicesTemplate; import org.mythtv.services.api.v025.beans.LiveStreamInfo; import org.mythtv.services.api.v025.beans.LiveStreamInfoList; import org.mythtv.services.api.v025.beans.Program; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import android.content.ContentProviderOperation; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.OperationApplicationException; import android.database.Cursor; import android.net.Uri; import android.os.RemoteException; import android.util.Log; /** * @author Daniel Frey * */ public class LiveStreamHelperV25 extends AbstractBaseHelper { private static final String TAG = LiveStreamHelperV25.class.getSimpleName(); private static final ApiVersion mApiVersion = ApiVersion.v025; private static PlaybackProfileDaoHelper mPlaybackProfileDaoHelper = PlaybackProfileDaoHelper.getInstance(); private static LiveStreamHelperV25 singleton; /** * Returns the one and only LiveStreamHelperV25. init() must be called before * any * @return */ public static LiveStreamHelperV25 getInstance() { if (null == singleton) { synchronized (LiveStreamHelperV25.class) { if (null == singleton) { singleton = new LiveStreamHelperV25(); } } } return singleton; } /** * Constructor. No one but getInstance() can do this. */ private LiveStreamHelperV25() { } public boolean create(final Context context, final LocationProfile locationProfile, final Integer channelId, final DateTime startTime) { Log.v(TAG, "create : enter"); if (!NetworkHelper.getInstance().isMasterBackendConnected(context, locationProfile)) { Log.w(TAG, "create : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return false; } MythServicesTemplate mMythServicesTemplate = (MythServicesTemplate) MythAccessFactory .getServiceTemplateApiByVersion(mApiVersion, locationProfile.getUrl()); if (null == mMythServicesTemplate) { Log.w(TAG, "create : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return false; } PlaybackProfile selectedPlaybackProfile = null; LocationType locationType = locationProfile.getType(); if (locationType.equals(LocationType.HOME)) { selectedPlaybackProfile = mPlaybackProfileDaoHelper.findSelectedHomeProfile(context); } else if (locationType.equals(LocationType.AWAY)) { selectedPlaybackProfile = mPlaybackProfileDaoHelper.findSelectedAwayProfile(context); } if (null != selectedPlaybackProfile) { try { Program program = RecordedHelperV25.getInstance().findRecorded(context, locationProfile, channelId, startTime); if (null != program) { ResponseEntity<LiveStreamInfo> wrapper = mMythServicesTemplate.contentOperations() .addLiveStream(program.getRecording().getStorageGroup(), program.getFileName(), program.getHostName(), null, null, selectedPlaybackProfile.getHeight(), selectedPlaybackProfile.getVideoBitrate(), selectedPlaybackProfile.getAudioBitrate(), selectedPlaybackProfile.getAudioSampleRate(), ETagInfo.createEmptyETag()); if (wrapper.getStatusCode().equals(HttpStatus.OK)) { LiveStreamInfo liveStreamInfo = wrapper.getBody(); save(context, locationProfile, liveStreamInfo, channelId, startTime); Log.v(TAG, "create : exit"); return true; } } } catch (Exception e) { Log.e(TAG, "create : error", e); } } Log.v(TAG, "create : exit, live stream NOT created"); return false; } public Integer load(final Context context, final LocationProfile locationProfile) { Log.v(TAG, "load : enter"); if (!NetworkHelper.getInstance().isMasterBackendConnected(context, locationProfile)) { Log.w(TAG, "update : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return null; } MythServicesTemplate mMythServicesTemplate = (MythServicesTemplate) MythAccessFactory .getServiceTemplateApiByVersion(mApiVersion, locationProfile.getUrl()); if (null == mMythServicesTemplate) { Log.w(TAG, "load : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return null; } Integer loaded = null; try { ResponseEntity<LiveStreamInfoList> wrapper = mMythServicesTemplate.contentOperations() .getLiveStreamList(EtagInfoDelegate.createEmptyETag()); if (wrapper.getStatusCode().equals(HttpStatus.OK)) { LiveStreamInfo[] liveStreams = wrapper.getBody().getLiveStreamInfos(); if (null != liveStreams && liveStreams.length > 0) { loaded = load(context, locationProfile, liveStreams); } Log.v(TAG, "update : exit"); return loaded; } } catch (Exception e) { Log.e(TAG, "update : error", e); } Log.v(TAG, "update : exit, live streams NOT loaded"); return loaded; } public boolean update(final Context context, final LocationProfile locationProfile, final long liveStreamId, final Integer channelId, final DateTime startTime) { Log.v(TAG, "update : enter"); if (!NetworkHelper.getInstance().isMasterBackendConnected(context, locationProfile)) { Log.w(TAG, "update : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return false; } MythServicesTemplate mMythServicesTemplate = (MythServicesTemplate) MythAccessFactory .getServiceTemplateApiByVersion(mApiVersion, locationProfile.getUrl()); if (null == mMythServicesTemplate) { Log.w(TAG, "update : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return false; } try { LiveStreamInfo liveStream = findLiveStream(context, locationProfile, liveStreamId); if (null != liveStream) { Log.v(TAG, "update : liveStream=" + liveStream.toString()); ResponseEntity<LiveStreamInfo> wrapper = mMythServicesTemplate.contentOperations() .getLiveStream(liveStream.getId(), EtagInfoDelegate.createEmptyETag()); if (wrapper.getStatusCode().equals(HttpStatus.OK)) { LiveStreamInfo updated = wrapper.getBody(); if (!"Unknown status value".equalsIgnoreCase(updated.getStatusStr())) { save(context, locationProfile, updated, channelId, startTime); } else { deleteLiveStream(context, liveStreamId); } Log.v(TAG, "update : exit"); return true; } } } catch (Exception e) { Log.e(TAG, "update : error", e); } Log.v(TAG, "update : exit, live stream NOT update"); return false; } public boolean remove(final Context context, final LocationProfile locationProfile, final Integer channelId, final DateTime startTime) { Log.v(TAG, "remove : enter"); if (!NetworkHelper.getInstance().isMasterBackendConnected(context, locationProfile)) { Log.w(TAG, "remove : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return false; } MythServicesTemplate mMythServicesTemplate = (MythServicesTemplate) MythAccessFactory .getServiceTemplateApiByVersion(mApiVersion, locationProfile.getUrl()); if (null == mMythServicesTemplate) { Log.w(TAG, "remove : Master Backend '" + locationProfile.getHostname() + "' is unreachable"); return false; } try { Program program = RecordedHelperV25.getInstance().findRecorded(context, locationProfile, channelId, startTime); if (null != program) { Log.v(TAG, "remove : program found"); LiveStreamInfo liveStream = findLiveStream(context, locationProfile, channelId, startTime); if (null != liveStream) { Log.v(TAG, "remove : program has live stream"); ResponseEntity<Bool> wrapper = mMythServicesTemplate.contentOperations() .removeLiveStream(liveStream.getId(), ETagInfo.createEmptyETag()); if (wrapper.getStatusCode().equals(HttpStatus.OK)) { Bool bool = wrapper.getBody(); if (bool.getValue()) { Log.v(TAG, "remove : live stream removed on backend"); boolean removed = deleteLiveStreamByLiveStreamId(context, locationProfile, liveStream.getId()); if (removed) { Log.v(TAG, "remove : exit"); return true; } } } } } } catch (Exception e) { Log.e(TAG, "remove : error", e); } Log.v(TAG, "remove : exit, live stream NOT removed"); return false; } public LiveStreamInfo findLiveStream(final Context context, final LocationProfile locationProfile, final Long id) { Log.d(TAG, "findLiveStream : enter"); String projection[] = null; String selection = LiveStreamConstants.FIELD_ID + " = ?"; String[] selectionArgs = new String[] { String.valueOf(id) }; LiveStreamInfo liveStreamInfo = null; Uri uri = LiveStreamConstants.CONTENT_URI; if (null != id && id > 0) { uri = ContentUris.withAppendedId(LiveStreamConstants.CONTENT_URI, id); } selection = appendLocationHostname(context, locationProfile, selection, LiveStreamConstants.TABLE_NAME); Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor.moveToFirst()) { liveStreamInfo = convertCursorToLiveStreamInfo(cursor); } cursor.close(); Log.d(TAG, "findLiveStream : exit"); return liveStreamInfo; } public LiveStreamInfo findLiveStream(final Context context, final LocationProfile locationProfile, final Integer channelId, final DateTime startTime) { Log.d(TAG, "findLiveStream : enter"); String projection[] = null; String selection = LiveStreamConstants.FIELD_CHAN_ID + " = ? AND " + LiveStreamConstants.FIELD_START_TIME + " = ?"; String[] selectionArgs = new String[] { String.valueOf(channelId), String.valueOf(startTime.getMillis()) }; LiveStreamInfo liveStreamInfo = null; selection = appendLocationHostname(context, locationProfile, selection, LiveStreamConstants.TABLE_NAME); Cursor cursor = context.getContentResolver().query(LiveStreamConstants.CONTENT_URI, projection, selection, selectionArgs, null); if (cursor.moveToFirst()) { liveStreamInfo = convertCursorToLiveStreamInfo(cursor); } cursor.close(); Log.d(TAG, "findLiveStream : exit"); return liveStreamInfo; } public boolean deleteLiveStream(final Context context, final Long id) { Log.d(TAG, "deleteLiveStream : enter"); if (null == context) throw new RuntimeException("LiveStreamHelperV25 is not initialized"); int deleted = context.getContentResolver() .delete(ContentUris.withAppendedId(LiveStreamConstants.CONTENT_URI, id), null, null); if (deleted == 1) { Log.v(TAG, "deleteLiveStream : exit"); return true; } Log.d(TAG, "deleteLiveStream : exit, live stream NOT deleted"); return false; } // internal helpers /** * @param liveStreamId * @return */ private boolean deleteLiveStreamByLiveStreamId(final Context context, final LocationProfile locationProfile, final Integer liveStreamId) { Log.d(TAG, "deleteLiveStreamByLiveStreamId : enter"); if (null == context) throw new RuntimeException("LiveStreamHelperV25 is not initialized"); String selection = LiveStreamConstants.FIELD_ID + " = ?"; String[] selectionArgs = new String[] { String.valueOf(liveStreamId) }; selection = appendLocationHostname(context, locationProfile, selection, LiveStreamConstants.TABLE_NAME); int deleted = context.getContentResolver().delete(LiveStreamConstants.CONTENT_URI, selection, selectionArgs); if (deleted == 1) { Log.v(TAG, "deleteLiveStreamByLiveStreamId : exit"); return true; } Log.d(TAG, "deleteLiveStreamByLiveStreamId : exit, live stream NOT deleted"); return false; } private Integer countLiveStreamsNotComplete(final Context context, final LocationProfile locationProfile) { Log.d(TAG, "countLiveStreamsNotComplete : enter"); String[] projection = new String[] { "count(" + LiveStreamConstants.TABLE_NAME + "." + LiveStreamConstants._ID + ")" }; String selection = "NOT " + LiveStreamConstants.TABLE_NAME + "." + LiveStreamConstants.FIELD_PERCENT_COMPLETE + " = ?"; String[] selectionArgs = new String[] { "100" }; selection = appendLocationHostname(context, locationProfile, selection, LiveStreamConstants.TABLE_NAME); Integer count = null; Cursor cursor = context.getContentResolver().query(LiveStreamConstants.CONTENT_URI, projection, selection, selectionArgs, null); if (cursor.moveToFirst()) { // Log.v( TAG, "findProgram : program=" + program.toString() ); count = cursor.getInt(0); } cursor.close(); Log.d(TAG, "countLiveStreamsNotComplete : exit"); return null != count ? count : 0; } private int load(final Context context, final LocationProfile locationProfile, LiveStreamInfo[] liveStreams) throws RemoteException, OperationApplicationException { Log.d(TAG, "load : enter"); if (null == context) { throw new RuntimeException("LiveStreamHelperV25 is not initialized"); } DateTime lastModified = new DateTime(DateTimeZone.UTC); int processed = -1; int count = 0; ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); for (LiveStreamInfo liveStream : liveStreams) { ContentValues values = convertLiveStreamInfoToContentValues(locationProfile, liveStream, lastModified, -1, null); String[] projection = new String[] { LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants._ID }; String selection = LiveStreamConstants.FIELD_ID + " = ?"; String[] selectionArgs = new String[] { String.valueOf(liveStream.getId()) }; selection = appendLocationHostname(context, locationProfile, selection, LiveStreamConstants.TABLE_NAME); Cursor cursor = context.getContentResolver().query(LiveStreamConstants.CONTENT_URI, projection, selection, selectionArgs, null); if (cursor.moveToFirst()) { Log.v(TAG, "load : updating existing liveStream info"); long id = cursor.getLong(cursor .getColumnIndexOrThrow(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants._ID)); context.getContentResolver().update(ContentUris.withAppendedId(LiveStreamConstants.CONTENT_URI, id), values, null, null); } cursor.close(); count++; if (count > BATCH_COUNT_LIMIT) { Log.i(TAG, "load : applying batch for '" + count + "' transactions, processing programs"); processBatch(context, ops, processed, count); count = 0; } } processBatch(context, ops, processed, count); Log.v(TAG, "load : remove deleted liveStreams"); String deletedSelection = LiveStreamConstants.TABLE_NAME + "." + LiveStreamConstants.FIELD_LAST_MODIFIED + " < ?"; String[] deletedSelectionArgs = new String[] { String.valueOf(lastModified.getMillis()) }; deletedSelection = appendLocationHostname(context, locationProfile, deletedSelection, LiveStreamConstants.TABLE_NAME); ops.add(ContentProviderOperation.newDelete(LiveStreamConstants.CONTENT_URI) .withSelection(deletedSelection, deletedSelectionArgs).withYieldAllowed(true).build()); processBatch(context, ops, processed, count); Intent progressIntent = new Intent(LiveStreamService.ACTION_PROGRESS); context.sendBroadcast(progressIntent); if (countLiveStreamsNotComplete(context, locationProfile) > 0) { Log.d(TAG, "load : further updates are required"); try { Thread.sleep(15000); } catch (InterruptedException e) { Log.e(TAG, "load : error", e); } processed = load(context, locationProfile); } Log.d(TAG, "load : exit"); return processed; } private boolean save(final Context context, final LocationProfile locationProfile, LiveStreamInfo liveStreamInfo, int channelId, DateTime startTime) { Log.d(TAG, "save : enter"); if (null == context) throw new RuntimeException("LiveStreamHelperV25 is not initialized"); DateTime lastModified = new DateTime(DateTimeZone.UTC); boolean saved = false; ContentValues values = convertLiveStreamInfoToContentValues(locationProfile, liveStreamInfo, lastModified, channelId, startTime); String[] projection = new String[] { LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants._ID }; String selection = LiveStreamConstants.FIELD_ID + " = ?"; String[] selectionArgs = new String[] { String.valueOf(liveStreamInfo.getId()) }; selection = appendLocationHostname(context, locationProfile, selection, LiveStreamConstants.TABLE_NAME); Cursor cursor = context.getContentResolver().query(LiveStreamConstants.CONTENT_URI, projection, selection, selectionArgs, null); if (cursor.moveToFirst()) { Log.v(TAG, "save : updating existing liveStream info"); long id = cursor.getLong( cursor.getColumnIndexOrThrow(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants._ID)); int updated = context.getContentResolver() .update(ContentUris.withAppendedId(LiveStreamConstants.CONTENT_URI, id), values, null, null); if (updated == 1) { saved = true; } } else { Log.v(TAG, "save : inserting new liveStream info"); Uri url = context.getContentResolver().insert(LiveStreamConstants.CONTENT_URI, values); if (ContentUris.parseId(url) > 0) { saved = true; } } cursor.close(); Log.d(TAG, "save : exit"); return saved; } private LiveStreamInfo convertCursorToLiveStreamInfo(Cursor cursor) { // Log.v( TAG, "convertCursorToLiveStreamInfo : enter" ); int id = -1, width = -1, height = -1, bitrate = -1, audioBitrate = -1, segmentSize = -1, maxSegments = -1, startSegment = -1, currentSegment = -1, segmentCount = -1, percentComplete = -1, statusInt = -1, sourceWidth = -1, sourceHeight = -1, audioOnlyBitrate = -1; String relativeUrl = "", fullUrl = "", statusStr = "", statusMessage = "", sourceFile = "", sourceHost = ""; DateTime created = null, lastModified = null; if (cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_ID) != -1) { id = cursor.getInt( cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_ID)); } if (cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_WIDTH) != -1) { width = cursor.getInt( cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_WIDTH)); } if (cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_HEIGHT) != -1) { height = cursor.getInt( cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_HEIGHT)); } if (cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_BITRATE) != -1) { bitrate = cursor.getInt(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_BITRATE)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_AUDIO_BITRATE) != -1) { audioBitrate = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_AUDIO_BITRATE)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SEGMENT_SIZE) != -1) { segmentSize = cursor.getInt(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SEGMENT_SIZE)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_MAX_SEGMENTS) != -1) { maxSegments = cursor.getInt(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_MAX_SEGMENTS)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_START_SEGMENT) != -1) { startSegment = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_START_SEGMENT)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_CURRENT_SEGMENT) != -1) { currentSegment = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_CURRENT_SEGMENT)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SEGMENT_COUNT) != -1) { segmentCount = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SEGMENT_COUNT)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_PERCENT_COMPLETE) != -1) { percentComplete = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_PERCENT_COMPLETE)); } if (cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_CREATED) != -1) { created = new DateTime(cursor.getLong(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_CREATED))); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_LAST_MODIFIED) != -1) { lastModified = new DateTime(cursor.getLong(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_LAST_MODIFIED))); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_RELATIVE_URL) != -1) { relativeUrl = cursor.getString(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_RELATIVE_URL)); } if (cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_FULL_URL) != -1) { fullUrl = cursor.getString(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_FULL_URL)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_STATUS_STR) != -1) { statusStr = cursor.getString(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_STATUS_STR)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_STATUS_INT) != -1) { statusInt = cursor.getInt(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_STATUS_INT)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_STATUS_MESSAGE) != -1) { statusMessage = cursor.getString(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_STATUS_MESSAGE)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_FILE) != -1) { sourceFile = cursor.getString(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_FILE)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_HOST) != -1) { sourceHost = cursor.getString(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_HOST)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_WIDTH) != -1) { sourceWidth = cursor.getInt(cursor .getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_WIDTH)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_HEIGHT) != -1) { sourceHeight = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_SOURCE_HEIGHT)); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_AUDIO_ONLY_BITRATE) != -1) { audioOnlyBitrate = cursor.getInt(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_AUDIO_ONLY_BITRATE)); } if (cursor.getColumnIndex(LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_CHAN_ID) != -1) { //Log.v( TAG, "convertCursorToLiveStreamInfo : chanId=" + cursor.getString( cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_CHAN_ID ) ) ); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_START_TIME) != -1) { //Log.v( TAG, "convertCursorToLiveStreamInfo : startTime=" + new DateTime( cursor.getLong( cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_START_TIME ) ) ) ); } if (cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_MASTER_HOSTNAME) != -1) { Log.v(TAG, "convertCursorToLiveStreamInfo : hostname=" + cursor.getString(cursor.getColumnIndex( LiveStreamConstants.TABLE_NAME + "_" + LiveStreamConstants.FIELD_MASTER_HOSTNAME))); } LiveStreamInfo liveStreamInfo = new LiveStreamInfo(); liveStreamInfo.setId(id); liveStreamInfo.setWidth(width); liveStreamInfo.setHeight(height); liveStreamInfo.setBitrate(bitrate); liveStreamInfo.setAudioBitrate(audioBitrate); liveStreamInfo.setSegmentSize(segmentSize); liveStreamInfo.setMaxSegments(maxSegments); liveStreamInfo.setStartSegment(startSegment); liveStreamInfo.setCurrentSegment(currentSegment); liveStreamInfo.setSegmentCount(segmentCount); liveStreamInfo.setPercentComplete(percentComplete); liveStreamInfo.setCreated(created); liveStreamInfo.setLastModified(lastModified); liveStreamInfo.setRelativeURL(relativeUrl); liveStreamInfo.setFullURL(fullUrl); liveStreamInfo.setStatusStr(statusStr); liveStreamInfo.setStatusInt(statusInt); liveStreamInfo.setStatusMessage(statusMessage); liveStreamInfo.setSourceFile(sourceFile); liveStreamInfo.setSourceHost(sourceHost); liveStreamInfo.setSourceWidth(sourceWidth); liveStreamInfo.setSourceHeight(sourceHeight); liveStreamInfo.setAudioOnlyBitrate(audioOnlyBitrate); // Log.v( TAG, "convertCursorToLiveStreamInfo : exit" ); return liveStreamInfo; } private ContentValues convertLiveStreamInfoToContentValues(final LocationProfile locationProfile, final LiveStreamInfo liveStreamInfo, final DateTime lastModified, final int channelId, final DateTime startTime) { // Log.v( TAG, "convertLiveStreamToContentValues : enter" ); ContentValues values = new ContentValues(); values.put(LiveStreamConstants.FIELD_ID, liveStreamInfo.getId()); values.put(LiveStreamConstants.FIELD_WIDTH, liveStreamInfo.getWidth()); values.put(LiveStreamConstants.FIELD_HEIGHT, liveStreamInfo.getHeight()); values.put(LiveStreamConstants.FIELD_BITRATE, liveStreamInfo.getBitrate()); values.put(LiveStreamConstants.FIELD_AUDIO_BITRATE, liveStreamInfo.getAudioBitrate()); values.put(LiveStreamConstants.FIELD_SEGMENT_SIZE, liveStreamInfo.getSegmentSize()); values.put(LiveStreamConstants.FIELD_MAX_SEGMENTS, liveStreamInfo.getMaxSegments()); values.put(LiveStreamConstants.FIELD_START_SEGMENT, liveStreamInfo.getStartSegment()); values.put(LiveStreamConstants.FIELD_CURRENT_SEGMENT, liveStreamInfo.getCurrentSegment()); values.put(LiveStreamConstants.FIELD_SEGMENT_COUNT, liveStreamInfo.getSegmentCount()); values.put(LiveStreamConstants.FIELD_PERCENT_COMPLETE, liveStreamInfo.getPercentComplete()); values.put(LiveStreamConstants.FIELD_CREATED, null != liveStreamInfo.getCreated() ? liveStreamInfo.getCreated().getMillis() : -1); values.put(LiveStreamConstants.FIELD_LAST_MODIFIED, null != liveStreamInfo.getLastModified() ? liveStreamInfo.getLastModified().getMillis() : -1); values.put(LiveStreamConstants.FIELD_RELATIVE_URL, liveStreamInfo.getRelativeURL()); values.put(LiveStreamConstants.FIELD_FULL_URL, liveStreamInfo.getFullURL()); values.put(LiveStreamConstants.FIELD_STATUS_STR, liveStreamInfo.getStatusStr()); values.put(LiveStreamConstants.FIELD_STATUS_INT, liveStreamInfo.getStatusInt()); values.put(LiveStreamConstants.FIELD_STATUS_MESSAGE, liveStreamInfo.getStatusMessage()); values.put(LiveStreamConstants.FIELD_SOURCE_FILE, liveStreamInfo.getSourceFile()); values.put(LiveStreamConstants.FIELD_SOURCE_HOST, liveStreamInfo.getSourceHost()); values.put(LiveStreamConstants.FIELD_SOURCE_WIDTH, liveStreamInfo.getSourceWidth()); values.put(LiveStreamConstants.FIELD_SOURCE_HEIGHT, liveStreamInfo.getSourceHeight()); values.put(LiveStreamConstants.FIELD_AUDIO_ONLY_BITRATE, liveStreamInfo.getAudioOnlyBitrate()); if (channelId > 0) { values.put(LiveStreamConstants.FIELD_CHAN_ID, channelId); } if (null != startTime) { values.put(LiveStreamConstants.FIELD_START_TIME, startTime.getMillis()); } values.put(LiveStreamConstants.FIELD_MASTER_HOSTNAME, locationProfile.getHostname()); values.put(LiveStreamConstants.FIELD_LAST_MODIFIED, lastModified.getMillis()); // Log.v( TAG, "convertLiveStreamToContentValues : exit" ); return values; } }