author | Lei Qian <lei.qian@amlogic.com> | 2018-01-04 08:27:25 (GMT) |
---|---|---|
committer | Gerrit Code Review <gituser@scgit.amlogic.com> | 2018-01-04 08:27:25 (GMT) |
commit | 281b967b2f0889c2404dcbd0ce56fdfd00c37c15 (patch) | |
tree | 66dc457809b9fd00baf33bd44fa6335fc00ccbab | |
parent | e2476e736ff34f8dc395d39461d82aebd1c50f22 (diff) | |
parent | 925b9a06d3d2edd7ecf083f6295b387bb6d35131 (diff) | |
download | tv-281b967b2f0889c2404dcbd0ce56fdfd00c37c15.zip tv-281b967b2f0889c2404dcbd0ce56fdfd00c37c15.tar.gz tv-281b967b2f0889c2404dcbd0ce56fdfd00c37c15.tar.bz2 |
Merge "tv-framework: batch store cacheed channel and delete repeated one [1/1]" into n-amlogic
-rw-r--r-- | core/java/com/droidlogic/app/tv/ChannelInfo.java | 15 | ||||
-rw-r--r-- | core/java/com/droidlogic/app/tv/TvDataBaseManager.java | 119 | ||||
-rw-r--r-- | core/java/com/droidlogic/app/tv/TvStoreManager.java | 165 |
3 files changed, 289 insertions, 10 deletions
diff --git a/core/java/com/droidlogic/app/tv/ChannelInfo.java b/core/java/com/droidlogic/app/tv/ChannelInfo.java index 98b07b4..9181277 100644 --- a/core/java/com/droidlogic/app/tv/ChannelInfo.java +++ b/core/java/com/droidlogic/app/tv/ChannelInfo.java @@ -677,6 +677,10 @@ public class ChannelInfo { mType = type; } + public void setId(long value) { + mId = value; + } + public void setDisplayNumber(String number) { mDisplayNumber = number; mNumber = stringToInteger(number); @@ -1282,6 +1286,17 @@ public class ChannelInfo { return (!mServiceType.equals(TvContract.Channels.SERVICE_TYPE_OTHER)); } + public boolean isSameChannel(ChannelInfo a) { + if (a == null) + return false; + + return a.getServiceId() == mServiceId + && a.getOriginalNetworkId() == mOriginalNetworkId + && a.getTransportStreamId() == mTransportStreamId + && a.getFrequency() == mFrequency + && TextUtils.equals(a.getDisplayName(), mDisplayName); + } + public void print () { Log.d(TAG, toString()); } diff --git a/core/java/com/droidlogic/app/tv/TvDataBaseManager.java b/core/java/com/droidlogic/app/tv/TvDataBaseManager.java index 4ee2378..b8ee7d7 100644 --- a/core/java/com/droidlogic/app/tv/TvDataBaseManager.java +++ b/core/java/com/droidlogic/app/tv/TvDataBaseManager.java @@ -754,6 +754,125 @@ public class TvDataBaseManager { } } + public void updateOrinsertChannelInList(ArrayList<ChannelInfo> updatelist, ArrayList<ChannelInfo> insertlist, boolean isdtv) { + ArrayList<ContentProviderOperation> ops = new ArrayList<>(); + for (ChannelInfo one : updatelist) { + long id = one.getId(); + if (id == -1) { + id = queryChannelIdInDb(one); + Log.d(TAG, "updateOrinsertChannelInList find id = " + id); + } + if (id < 0) { + ops.add(creatOperation(isdtv, false, id, one)); + } else { + ops.add(creatOperation(isdtv, true, id, one)); + } + Log.d(TAG, "updateOrinsertChannelInList add update = " + one.getDisplayNumber()); + } + for (ChannelInfo one : insertlist) { + ops.add(creatOperation(isdtv, false, -1, one)); + Log.d(TAG, "updateOrinsertChannelInList add insert = " + one.getDisplayNumber()); + } + try { + mContentResolver.applyBatch(TvContract.AUTHORITY, ops); + } catch (RemoteException | OperationApplicationException e) { + Log.e(TAG, "updateOrinsertChannelInList Failed = " + e.getMessage()); + } + ops.clear(); + } + + private ContentProviderOperation creatOperation(boolean isdtv, boolean isupdate, long id, ChannelInfo ch) { + if (isdtv) { + if (isupdate) { + return ContentProviderOperation.newUpdate( + TvContract.buildChannelUri(id)) + .withValues(buildDtvChannelData(ch)) + .build(); + } else { + return ContentProviderOperation.newInsert( + TvContract.Channels.CONTENT_URI) + .withValues(buildDtvChannelData(ch)) + .build(); + } + } else { + if (isupdate) { + return ContentProviderOperation.newUpdate( + TvContract.buildChannelUri(id)) + .withValues(buildAtvChannelData(ch)) + .build(); + } else { + return ContentProviderOperation.newInsert( + TvContract.Channels.CONTENT_URI) + .withValues(buildAtvChannelData(ch)) + .build(); + } + } + } + + public long queryChannelIdInDb(ChannelInfo channel) { + long id = -1;//-1 means not init; -2 means not exist + if (channel != null) { + id = channel.getId(); + if (id > -1) { + return id; + } + } else { + return id; + } + Uri channelsUri = TvContract.buildChannelsUriForInput(channel.getInputId()); + String[] projection = {Channels._ID, + Channels.COLUMN_SERVICE_ID, + Channels.COLUMN_ORIGINAL_NETWORK_ID, + Channels.COLUMN_TRANSPORT_STREAM_ID, + Channels.COLUMN_DISPLAY_NUMBER, + Channels.COLUMN_DISPLAY_NAME, + Channels.COLUMN_INTERNAL_PROVIDER_DATA}; + + Cursor cursor = null; + try { + boolean found = false; + cursor = mContentResolver.query(channelsUri, projection, Channels.COLUMN_SERVICE_TYPE + "=?", new String[]{channel.getServiceType()}, null); + while (cursor != null && cursor.moveToNext()) { + long rowId = cursor.getLong(findPosition(projection, Channels._ID)); + + if (channel.getId() == -1) { + int serviceId = cursor.getInt(findPosition(projection, Channels.COLUMN_SERVICE_ID)); + int originalNetworkId = cursor.getInt(findPosition(projection, Channels.COLUMN_ORIGINAL_NETWORK_ID)); + int transportStreamId = cursor.getInt(findPosition(projection, Channels.COLUMN_TRANSPORT_STREAM_ID)); + String name = cursor.getString(findPosition(projection, Channels.COLUMN_DISPLAY_NAME)); + int frequency = 0; + int index = cursor.getColumnIndex(Channels.COLUMN_INTERNAL_PROVIDER_DATA); + if (index >= 0) { + Map<String, String> parsedMap = DroidLogicTvUtils.jsonToMap(cursor.getString(index)); + frequency = Integer.parseInt(parsedMap.get(ChannelInfo.KEY_FREQUENCY)); + } + if ((serviceId == channel.getServiceId() + && originalNetworkId == channel.getOriginalNetworkId() + && transportStreamId == channel.getTransportStreamId() + && frequency == channel.getFrequency() + && TextUtils.equals(name, channel.getDisplayName())) || (channel.isAnalogChannel() && frequency == channel.getFrequency())) + found = true; + } + + if (found) { + id = rowId; + return id; + } + } + if (id == -1) + return -2; + } catch (Exception e) { + //TODO + Log.e(TAG, "queryChannelIdInDb Failed = " + e.getMessage()); + e.printStackTrace(); + } finally { + if (cursor != null) { + cursor.close(); + } + } + return -1; + } + // If a channel exists, update it. If not, insert a new one. public void updateOrinsertAtvChannel(ChannelInfo channel) { int updateRet = updateAtvChannel(channel); diff --git a/core/java/com/droidlogic/app/tv/TvStoreManager.java b/core/java/com/droidlogic/app/tv/TvStoreManager.java index 61b350b..450957c 100644 --- a/core/java/com/droidlogic/app/tv/TvStoreManager.java +++ b/core/java/com/droidlogic/app/tv/TvStoreManager.java @@ -9,6 +9,11 @@ import android.util.Log; import android.os.Bundle; import android.content.Context; import android.media.tv.TvContract; +import android.os.Handler; +import android.os.Message; +import android.text.TextUtils; +import android.os.SystemProperties; +import android.os.HandlerThread; import com.droidlogic.app.tv.TvControlManager; import com.droidlogic.app.tv.TvControlManager.FreqList; @@ -34,11 +39,13 @@ public abstract class TvStoreManager { /*for store in search*/ private boolean isFinalStoreStage = false; private boolean isRealtimeStore = true; - + private HandlerThread mhandlerThread; + private Handler mChildHandler; private ArrayList<ChannelInfo> mChannelsOld = null; private ArrayList<ChannelInfo> mChannelsNew = null; private ArrayList<ChannelInfo> mChannelsExist = null; + private ArrayList<ChannelInfo> mChannelsAll = null; private ArrayList<FreqList> mATSC_T = null; private ArrayList<FreqList> mATSC_C_STD = null; @@ -62,6 +69,9 @@ public abstract class TvStoreManager { mTvControlManager = TvControlManager.getInstance(); display_number_start = mInitialDisplayNumber; lcn_overflow_start = mInitialLcnNumber; + mhandlerThread = new HandlerThread("dealevent"); + mhandlerThread.start(); + mChildHandler = new Handler(mhandlerThread.getLooper(), new ChildCallback()); } public void setInitialLcnNumber(int initialLcnNumber) { @@ -170,6 +180,9 @@ public abstract class TvStoreManager { mChannelsOld.addAll(mTvDataBaseManager.getChannelList(mInputId, TvContract.Channels.SERVICE_TYPE_OTHER)); Log.d(TAG, "Store> channel next:" + mDisplayNumber); } + if (mChannelsAll == null) { + mChannelsAll = new ArrayList<ChannelInfo>(); + } } private void reinitChannels() { if (mChannelsExist == null) { @@ -177,6 +190,9 @@ public abstract class TvStoreManager { mChannelsExist.addAll(mTvDataBaseManager.getChannelList(mInputId, TvContract.Channels.SERVICE_TYPE_AUDIO)); mChannelsExist.addAll(mTvDataBaseManager.getChannelList(mInputId, TvContract.Channels.SERVICE_TYPE_OTHER)); } + if (mChannelsAll == null) { + mChannelsAll = new ArrayList<ChannelInfo>(); + } } private ChannelInfo createDtvChannelInfo(TvControlManager.ScannerEvent event) { String name = null; @@ -359,9 +375,14 @@ public abstract class TvStoreManager { if (mChannelsNew == null) mChannelsNew = new ArrayList(); - mChannelsNew.add(channel); + //not add the same channel + int newindex = dealRepeatCacheChannels(channel); + if (newindex > -1) { + channel = mChannelsNew.get(newindex); + Log.d(TAG, "cacheChannel update id = " + channel.getId()); + } - Log.d(TAG, "store save [" + channel.getDisplayNumber() + "][" + channel.getFrequency() + "][" + channel.getServiceType() + "][" + channel.getDisplayName() + "]"); + Log.d(TAG, "store save [" + channel.getDisplayNumber() + "][" + channel.getFrequency() + "][" + channel.getServiceType() + "][" + channel.getDisplayName() + "][" + channel.getId() + "]"); if (mScanMode.isDTVManulScan() || mScanMode.isATVManualScan()) { if (on_channel_store_tschanged) { @@ -371,6 +392,53 @@ public abstract class TvStoreManager { } } + private int dealRepeatCacheChannels(ChannelInfo ch) { + if (ch == null) { + return -1; + } + boolean hasaddtoall = false; + for (int j = 0; j < mChannelsAll.size(); j++) { + ChannelInfo tempch = mChannelsAll.get(j); + if (tempch != null && tempch.isSameChannel(ch)) { + if (tempch.getId() < 0) { + long id = mTvDataBaseManager.queryChannelIdInDb(tempch); + if (id > -1) { + ch.setId(id); + } + } else { + ch.setId(tempch.getId()); + } + + mChannelsAll.remove(j); + mChannelsAll.add(j, ch); + hasaddtoall = true; + Log.d(TAG, "dealRepeatCacheChannels exist in all = " + mChannelsAll.get(j).getDisplayNumber() + ", id = " + mChannelsAll.get(j).getId() + ", type = " + mChannelsAll.get(j).getType()); + if (ch.isAnalogChannel() || ch.isAtscChannel()) { + return -1;//atsc and analog channel don't need to cache the same channel as dtmb channel DisplayNumber may change + } + } + } + if (!hasaddtoall) { + mChannelsAll.add(ch); + Log.d(TAG, "dealRepeatCacheChannels not exist in all = " + ch.getDisplayNumber()); + } + boolean hasaddtonew = false; + for (int i = 0; i < mChannelsNew.size(); i++) { + ChannelInfo tempch = mChannelsNew.get(i); + if (tempch != null && tempch.isSameChannel(ch)) { + Log.d(TAG, "dealRepeatCacheChannels exist in new = " + tempch.getDisplayNumber()); + mChannelsNew.remove(i); + mChannelsNew.add(i, ch); + hasaddtonew = true; + return i; + } + } + if (!hasaddtonew) { + mChannelsNew.add(ch); + Log.d(TAG, "dealRepeatCacheChannels not exist in new = " + ch.getDisplayNumber()); + } + return mChannelsNew.size() -1; + } private boolean isChannelInListbyId(ChannelInfo channel, ArrayList<ChannelInfo> list) { if (list == null) @@ -589,6 +657,12 @@ public abstract class TvStoreManager { private void storeTvChannel(boolean isRealtimeStore, boolean isFinalStore) { Bundle bundle = null; + ArrayList<ChannelInfo> dtvchannelsnew= new ArrayList<ChannelInfo>(); + ArrayList<ChannelInfo> atvchannelsnew= new ArrayList<ChannelInfo>(); + ArrayList<ChannelInfo> dtvchannelsinsert; + ArrayList<ChannelInfo> dtvchannelsupdate; + ArrayList<ChannelInfo> atvchannelsinsert; + ArrayList<ChannelInfo> atvchannelsupdate; Log.d(TAG, "isRealtimeStore:" + isRealtimeStore + " isFinalStore:"+ isFinalStore); @@ -630,10 +704,13 @@ public abstract class TvStoreManager { } if (isRealtimeStore) { - if (c.isAnalogChannel()) - mTvDataBaseManager.updateOrinsertAtvChannelWithNumber(c); - else - mTvDataBaseManager.updateOrinsertDtvChannelWithNumber(c); + if (c.isAnalogChannel()) { + //mTvDataBaseManager.updateOrinsertAtvChannelWithNumber(c); + atvchannelsnew.add(c); + } else { + //mTvDataBaseManager.updateOrinsertDtvChannelWithNumber(c); + dtvchannelsnew.add(c); + } } else { if (c.isAnalogChannel()) mTvDataBaseManager.insertAtvChannel(c, c.getDisplayNumber()); @@ -641,8 +718,8 @@ public abstract class TvStoreManager { mTvDataBaseManager.insertDtvChannel(c, c.getDisplayNumber()); } - Log.d(TAG, ((isRealtimeStore) ? "update/insert [" : "insert [") + c.getDisplayNumber() - + "][" + c.getFrequency() + "][" + c.getServiceType() + "][" + c.getDisplayName() + "]"); + /*Log.d(TAG, ((isRealtimeStore) ? "update/insert [" : "insert [") + c.getDisplayNumber() + + "][" + c.getFrequency() + "][" + c.getServiceType() + "][" + c.getDisplayName() + "]");*/ if (isFinalStore) { bundle = getDisplayNumBunlde(c.getNumber()); @@ -650,6 +727,16 @@ public abstract class TvStoreManager { } } } + if (atvchannelsnew != null && atvchannelsnew.size() > 0) { + atvchannelsupdate = getNeedUpdateChannel(atvchannelsnew); + atvchannelsinsert= getNeedInsertChannel(atvchannelsnew); + mTvDataBaseManager.updateOrinsertChannelInList(atvchannelsupdate, atvchannelsinsert, false); + } + if (dtvchannelsnew != null && dtvchannelsnew.size() > 0) { + dtvchannelsupdate = getNeedUpdateChannel(dtvchannelsnew); + dtvchannelsinsert= getNeedInsertChannel(dtvchannelsnew); + mTvDataBaseManager.updateOrinsertChannelInList(dtvchannelsupdate, dtvchannelsinsert, true); + } lcn_overflow_start = mInitialLcnNumber; display_number_start = mInitialDisplayNumber; @@ -659,6 +746,45 @@ public abstract class TvStoreManager { mChannelsExist = null; } + private ArrayList<ChannelInfo> getNeedUpdateChannel(ArrayList<ChannelInfo> list) { + ArrayList<ChannelInfo> needupdate = new ArrayList<ChannelInfo>(); + for (int i = 0; i < list.size(); i++) { + for (int j = 0; j < mChannelsAll.size(); j++) { + ChannelInfo tempch = mChannelsAll.get(j); + if (tempch != null && TextUtils.equals(tempch.getDisplayNumber(), list.get(i).getDisplayNumber()) && tempch.getFrequency() == list.get(i).getFrequency()) { + ChannelInfo updateinfo = list.get(i); + if (tempch.getId() > -1) { + updateinfo.setId(tempch.getId()); + } + needupdate.add(updateinfo); + } + } + } + Log.d(TAG, "getNeedUpdateChannel size = " + needupdate.size()); + return needupdate; + } + + private ArrayList<ChannelInfo> getNeedInsertChannel(ArrayList<ChannelInfo> list) { + ArrayList<ChannelInfo> needinsert = new ArrayList<ChannelInfo>(); + boolean exist = false; + for (int i = 0; i < list.size(); i++) { + for (int j = 0; j < mChannelsAll.size(); j++) { + ChannelInfo tempch = mChannelsAll.get(j); + if (tempch != null && TextUtils.equals(tempch.getDisplayNumber(), list.get(i).getDisplayNumber()) && tempch.getFrequency() == list.get(i).getFrequency()) { + exist = true; + break; + } + } + if (!exist) { + needinsert.add(list.get(i)); + } else { + exist = false; + } + } + Log.d(TAG, "getNeedInsertChannel size = " + needinsert.size()); + return needinsert; + } + private boolean getIsSameDisplayNumber(ChannelInfo chan) { int size = mChannelsExist.size(); for (int i = 0; i < size; i++) { @@ -730,6 +856,17 @@ public abstract class TvStoreManager { return physicalNum; } public void onStoreEvent(TvControlManager.ScannerEvent event) { + sendStoreEvent(event); + } + + private void sendStoreEvent(TvControlManager.ScannerEvent event) { + Message msg = new Message(); + msg.arg1 = event.type; + msg.obj = event; + mChildHandler.sendMessage(msg); + } + + public void dealStoreEvent(TvControlManager.ScannerEvent event) { ChannelInfo channel = null; String name = null; Bundle bundle = null; @@ -870,7 +1007,7 @@ public abstract class TvStoreManager { break; case TvControlManager.EVENT_SCAN_PROGRESS: - Log.d(TAG, event.precent + "%\tfreq[" + event.freq + "] lock[" + event.lock + "] strength[" + event.strength + "] quality[" + event.quality + "]"); + Log.d(TAG, event.precent + "%\tfreq[" + event.freq + "] lock[" + event.lock + "] strength[" + event.strength + "] quality[" + event.quality + "] mode[" + event.mode + "]"); checkOrPatchBeginLost(event); @@ -935,6 +1072,7 @@ public abstract class TvStoreManager { } mScanMode = null; + mChannelsAll = null; onScanExit(); @@ -947,5 +1085,12 @@ public abstract class TvStoreManager { } } + private class ChildCallback implements Handler.Callback { + @Override + public boolean handleMessage(Message msg) { + dealStoreEvent((TvControlManager.ScannerEvent)msg.obj); + return false; + } + } } |