summaryrefslogtreecommitdiff
authorTellen Yu <tellen.yu@amlogic.com>2018-01-10 07:26:56 (GMT)
committer Tellen Yu <tellen.yu@amlogic.com>2018-01-11 06:13:15 (GMT)
commitc4c6ed9cc1d00327464814f330326b5bb5cf7298 (patch)
tree979b86781c584c0e91e407d47a20d4061a2ea05a
parent285017f2b105f35cd0c2b1a46a26860249d3b542 (diff)
parentbcaa474b05395100d7a915a085a6015afd8db2ce (diff)
downloadtv-c4c6ed9cc1d00327464814f330326b5bb5cf7298.zip
tv-c4c6ed9cc1d00327464814f330326b5bb5cf7298.tar.gz
tv-c4c6ed9cc1d00327464814f330326b5bb5cf7298.tar.bz2
Merge remote-tracking branch 'remotes/amlogic/n-amlogic' into HEAD
Change-Id: I428d174ea6b46a244aac0070d9228391a603a3ae
Diffstat
-rw-r--r--core/java/com/droidlogic/app/tv/ChannelInfo.java129
-rw-r--r--core/java/com/droidlogic/app/tv/DroidContentRatingsParser.java328
-rw-r--r--core/java/com/droidlogic/app/tv/DroidLogicOverlayView.java15
-rw-r--r--core/java/com/droidlogic/app/tv/DroidLogicTvInputService.java20
-rw-r--r--core/java/com/droidlogic/app/tv/DroidLogicTvUtils.java91
-rw-r--r--core/java/com/droidlogic/app/tv/EasEvent.java152
-rw-r--r--core/java/com/droidlogic/app/tv/EasManager.java33
-rw-r--r--core/java/com/droidlogic/app/tv/Program.java70
-rw-r--r--core/java/com/droidlogic/app/tv/TVTime.java7
-rw-r--r--core/java/com/droidlogic/app/tv/TvControlCommand.java19
-rw-r--r--core/java/com/droidlogic/app/tv/TvControlManager.java291
-rw-r--r--core/java/com/droidlogic/app/tv/TvDataBaseManager.java345
-rw-r--r--core/java/com/droidlogic/app/tv/TvInputBaseSession.java24
-rw-r--r--core/java/com/droidlogic/app/tv/TvStoreManager.java321
-rw-r--r--libtvbinder/include/tvcmd.h20
15 files changed, 1767 insertions, 98 deletions
diff --git a/core/java/com/droidlogic/app/tv/ChannelInfo.java b/core/java/com/droidlogic/app/tv/ChannelInfo.java
index a03fffc..9181277 100644
--- a/core/java/com/droidlogic/app/tv/ChannelInfo.java
+++ b/core/java/com/droidlogic/app/tv/ChannelInfo.java
@@ -30,6 +30,7 @@ public class ChannelInfo {
Channels.COLUMN_VIDEO_FORMAT,
Channels.COLUMN_INTERNAL_PROVIDER_DATA,
Channels.COLUMN_BROWSABLE,
+ TvContract.Channels.COLUMN_LOCKED,
COLUMN_LCN,
COLUMN_LCN1,
COLUMN_LCN2
@@ -59,6 +60,7 @@ public class ChannelInfo {
public static final String KEY_AUDIO_LANGS = "audio_langs";
public static final String KEY_AUDIO_EXTS = "audio_exts";
public static final String KEY_AUDIO_TRACK_INDEX = "audio_track_index";
+ public static final String KEY_AUDIO_OUTPUT_MODE = "audio_out_mode";
public static final String KEY_AUDIO_COMPENSATION = "audio_compensation";
public static final String KEY_AUDIO_CHANNEL = "audio_channel";
public static final String KEY_AUDIO_STD = "audio_std";
@@ -95,8 +97,12 @@ public class ChannelInfo {
public static final String KEY_ACCESS_CONTROL = "access";
public static final String KEY_HIDDEN = "hidden";
public static final String KEY_HIDE_GUIDE = "hideGuide";
+ public static final String KEY_VCT = "vct";
+ public static final String KEY_EITV = "eitv";
public static final String EXTRA_CHANNEL_INFO = "extra_channel_info";
+ public static final String KEY_CONTENT_RATINGS = "content_ratings";
+ public static final String KEY_SIGNAL_TYPE = "signal_type";
public static final String LABEL_ATV = "ATV";
public static final String LABEL_DTV = "DTV";
@@ -136,6 +142,7 @@ public class ChannelInfo {
private int mAudioTrackIndex; //-1:not select, -2:off, >=0:index
private int mAudioCompensation;
private int mAudioChannel;
+ private int mAudioOutPutMode;//-1:not set 0:mono 1:stereo 2:sap
private int mPcrPid;
@@ -176,6 +183,11 @@ public class ChannelInfo {
private int mAccessControlled;
private int mHidden;
private int mHideGuide;
+ private String mVct;
+ private int[] mEitVersions;
+
+ private String mContentRatings;
+ private String mSignalType;
private ChannelInfo() {}
@@ -272,9 +284,14 @@ public class ChannelInfo {
builder.setVideoPid(Integer.parseInt(parsedMap.get(KEY_VIDEO_PID)));
if (parsedMap.get(KEY_PCR_ID) != null)
builder.setPcrPid(Integer.parseInt(parsedMap.get(KEY_PCR_ID)));
-
+ if (parsedMap.get(KEY_CONTENT_RATINGS) != null)
+ builder.setContentRatings(DroidLogicTvUtils.TvString.fromString(parsedMap.get(KEY_CONTENT_RATINGS)));
+ if (parsedMap.get(KEY_SIGNAL_TYPE) != null)
+ builder.setSignalType(DroidLogicTvUtils.TvString.fromString(parsedMap.get(KEY_SIGNAL_TYPE)));
if (parsedMap.get(KEY_AUDIO_TRACK_INDEX) != null)
builder.setAudioTrackIndex(Integer.parseInt(parsedMap.get(KEY_AUDIO_TRACK_INDEX)));
+ if (parsedMap.get(KEY_AUDIO_OUTPUT_MODE) != null)
+ builder.setAudioOutPutMode(Integer.parseInt(parsedMap.get(KEY_AUDIO_OUTPUT_MODE)));
if (parsedMap.get(KEY_AUDIO_COMPENSATION) != null)
builder.setAudioCompensation(Integer.parseInt(parsedMap.get(KEY_AUDIO_COMPENSATION)));
if (parsedMap.get(KEY_AUDIO_CHANNEL) != null)
@@ -348,12 +365,28 @@ public class ChannelInfo {
builder.setHidden(Integer.parseInt(parsedMap.get(KEY_HIDDEN)));
if (parsedMap.get(KEY_HIDE_GUIDE) != null)
builder.setHideGuide(Integer.parseInt(parsedMap.get(KEY_HIDE_GUIDE)));
+ if (parsedMap.get(KEY_VCT) != null)
+ builder.setVct(parsedMap.get(KEY_VCT));
+ if (parsedMap.get(KEY_EITV) != null) {
+ String[] svs = parsedMap.get(KEY_EITV).replace("[", "").replace("]", "").split(",");
+ int vn = (svs[0].compareTo("null") == 0)? 0 : svs.length;
+ if (vn > 0) {
+ int[] vs = new int[vn];
+ for (int i = 0; i < vn; i++)
+ vs[i] = Integer.parseInt(svs[i]);
+ builder.setEitVersions(vs);
+ }
+ }
}
index = cursor.getColumnIndex(Channels.COLUMN_BROWSABLE);
if (index >= 0)
builder.setBrowsable(cursor.getInt(index)==1 ? true : false);
+ index = cursor.getColumnIndex(Channels.COLUMN_LOCKED);
+ if (index >= 0)
+ builder.setLocked(cursor.getInt(index)==1 ? true : false);
+
index = cursor.getColumnIndex(COLUMN_LCN);
if (index >= 0)
builder.setLCN(cursor.getInt(index));
@@ -465,6 +498,10 @@ public class ChannelInfo {
return mAudioTrackIndex;
}
+ public int getAudioOutPutMode() {
+ return mAudioOutPutMode;
+ }
+
public int getAudioCompensation() {
return mAudioCompensation;
}
@@ -481,6 +518,22 @@ public class ChannelInfo {
return mFrequency;
}
+ public String getContentRatings() {
+ return mContentRatings;
+ }
+
+ public String getSignalType() {
+ return mSignalType;
+ }
+
+ public void setSignalType(String signalType) {
+ mSignalType = signalType;
+ }
+
+ public void setContentRatings(String contentRatings) {
+ mContentRatings = contentRatings;
+ }
+
public int getBandwidth() {
return mBandwidth;
}
@@ -589,6 +642,14 @@ public class ChannelInfo {
return mHideGuide;
}
+ public String getVct() {
+ return mVct;
+ }
+
+ public int[] getEitVersions() {
+ return mEitVersions;
+ }
+
public boolean isBrowsable() {
return this.mBrowsable;
}
@@ -616,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);
@@ -673,6 +738,10 @@ public class ChannelInfo {
mAudioTrackIndex = index;
}
+ public void setAudioOutPutMode(int mode) {
+ mAudioOutPutMode = mode;
+ }
+
public void setAudioCompensation(int value) {
mAudioCompensation = value;
}
@@ -689,6 +758,10 @@ public class ChannelInfo {
mBrowsable = enable;
}
+ public void setLocked(boolean enable) {
+ mLocked = enable;
+ }
+
public void setFavourite(boolean enable) {
mIsFavourite = enable;
}
@@ -753,6 +826,10 @@ public class ChannelInfo {
mLCN2 = lcn;
}
+ public void setEitVersions(int[] versions) {
+ mEitVersions = versions;
+ }
+
public void copyFrom(ChannelInfo channel) {
if (this == channel)
return;
@@ -799,11 +876,14 @@ public class ChannelInfo {
mChannel.mAudioStd = -1;
mChannel.mIsAutoStd = -1;
mChannel.mAudioTrackIndex = -1;
+ mChannel.mAudioOutPutMode = -1;
mChannel.mAudioCompensation = -1;
mChannel.mAudioChannel = 0;
mChannel.mPcrPid = -1;
mChannel.mFrequency = -1;
+ mChannel.mContentRatings = "";
+ mChannel.mSignalType = "";
mChannel.mBandwidth = -1;
mChannel.mSymbolRate = -1;
mChannel.mModulation = -1;
@@ -838,6 +918,8 @@ public class ChannelInfo {
mChannel.mAccessControlled = 0;
mChannel.mHidden = 0;
mChannel.mHideGuide = 0;
+ mChannel.mVct = null;
+ mChannel.mEitVersions = null;
}
public Builder setId(long id) {
@@ -956,6 +1038,11 @@ public class ChannelInfo {
return this;
}
+ public Builder setAudioOutPutMode(int mode) {
+ mChannel.mAudioOutPutMode = mode;
+ return this;
+ }
+
public Builder setAudioCompensation(int c) {
mChannel.mAudioCompensation = c;
return this;
@@ -976,6 +1063,16 @@ public class ChannelInfo {
return this;
}
+ public Builder setContentRatings(String contentRatings) {
+ mChannel.mContentRatings = contentRatings;
+ return this;
+ }
+
+ public Builder setSignalType(String signalType) {
+ mChannel.mSignalType = signalType;
+ return this;
+ }
+
public Builder setBandwidth(int w) {
mChannel.mBandwidth = w;
return this;
@@ -1121,6 +1218,16 @@ public class ChannelInfo {
return this;
}
+ public Builder setVct(String vct) {
+ mChannel.mVct = vct;
+ return this;
+ }
+
+ public Builder setEitVersions(int[] versions) {
+ mChannel.mEitVersions = versions;
+ return this;
+ }
+
public ChannelInfo build() {
return mChannel;
}
@@ -1179,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());
}
@@ -1206,6 +1324,7 @@ public class ChannelInfo {
"\n AudioStd = " + mAudioStd +
"\n IsAutoStd = " + mIsAutoStd +
"\n AudioTrackIndex = " + mAudioTrackIndex +
+ "\n mAudioOutPutMode = " + mAudioOutPutMode +
"\n AudioCompensation = " + mAudioCompensation +
"\n AudioChannel = " + mAudioChannel +
"\n PcrPid = " + mPcrPid +
@@ -1232,7 +1351,11 @@ public class ChannelInfo {
"\n mSourceId = " + mSourceId +
"\n AccessControled = " + mAccessControlled +
"\n Hidden = " + mHidden +
- "\n HideGuide = " + mHideGuide;
+ "\n HideGuide = " + mHideGuide +
+ "\n Ratings = " + mContentRatings +
+ "\n SignalType = " + mSignalType +
+ "\n vct = " + mVct +
+ "\n EitVers = " + Arrays.toString(mEitVersions);
}
public static class Subtitle {
@@ -1259,6 +1382,8 @@ public class ChannelInfo {
public static final int CC_CAPTION_SERVICE4 = 12;
public static final int CC_CAPTION_SERVICE5 = 13;
public static final int CC_CAPTION_SERVICE6 = 14;
+ /*xds vchip services*/
+ public static final int CC_CAPTION_VCHIP_ONLY = 15;
public int mType;
public int mPid;
diff --git a/core/java/com/droidlogic/app/tv/DroidContentRatingsParser.java b/core/java/com/droidlogic/app/tv/DroidContentRatingsParser.java
new file mode 100644
index 0000000..50816d4
--- a/dev/null
+++ b/core/java/com/droidlogic/app/tv/DroidContentRatingsParser.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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.droidlogic.app.tv;
+
+import android.content.ContentUris;
+import android.content.Context;
+//import android.content.pm.PackageManager.NameNotFoundException;
+//import android.content.res.Resources;
+//import android.content.res.XmlResourceParser;
+import android.media.tv.TvContentRatingSystemInfo;
+//import android.net.Uri;
+import android.util.Log;
+
+//import com.android.tv.parental.ContentRatingSystem.Order;
+//import com.android.tv.parental.ContentRatingSystem.Rating;
+//import com.android.tv.parental.ContentRatingSystem.SubRating;
+
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.List;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+
+
+import android.content.Context;
+import android.content.Intent;
+//import android.media.tv.TvContentRating;
+//import android.media.tv.TvInputManager;
+//import android.os.Environment;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.Xml;
+
+//import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
+
+
+import libcore.io.IoUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DroidContentRatingsParser {
+ private static final String TAG = "DroidContentRatingsParser";
+ private static final boolean DEBUG = false;
+
+ public static final String DOMAIN_RRT_RATINGS = "com.droidlogic.app.tv";
+ public static final int FIXED_REGION_lEVEL_2 = 2;
+
+ private static final String TAG_RATING_SYSTEM_DEFINITIONS = "rating-system-definitions";
+ private static final String TAG_RATING_SYSTEM_DEFINITION = "rating-system-definition";
+ private static final String TAG_RATING_DEFINITION = "rating-definition";
+
+ private static final String ATTR_STRING = "string";
+ private static final String ATTR_ENABLED = "enabled";
+
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_RATING = "rating";
+ private static final String ATTR_COUNTRY = "country";
+ private static final String ATTR_DIMENSION_ID = "dimension_id";
+ private static final String ATTR_TITLE = "title";
+ private static final String ATTR_DESCRIPTION = "description";
+ private static final String ATTR_RADING_ID = "rating_id";
+
+ //private final Context mContext;
+ //private Resources mResources;
+ private String mXmlVersionCode;
+ private final Object mLock = new Object();
+
+ private AtomicFile mAtomicFile_t;
+ public DroidContentRatingsParser() {
+ //mContext = context;
+ File userDir = new File("/param");//Environment.getDataSystemDirectory();
+ if (!userDir.exists()) {
+ if (!userDir.mkdirs()) {
+ throw new IllegalStateException("User dir cannot be created: " + userDir);
+ }
+ }
+ mAtomicFile_t = new AtomicFile(new File(userDir, "tv_rrt_define.xml"));
+ }
+
+ public List<ContentRatingSystemT> load_t() {
+ //clearState();
+ synchronized (mLock) {
+ final InputStream is;
+ Log.d(TAG, "==== start load_t====");
+ try {
+ is = mAtomicFile_t.openRead();
+ } catch (FileNotFoundException ex) {
+ Log.d(TAG, "==== load FileNotFoundException====");
+ return null;
+ }
+
+ XmlPullParser parser;
+ try {
+ parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
+ return loadFromXml_t(parser);
+ } catch (IOException | XmlPullParserException ex) {
+ Log.w(TAG, "Failed to load tv input manager persistent store data.", ex);
+ //clearState();
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+ return null;
+ }
+ }
+ private List<ContentRatingSystemT> loadFromXml_t(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ List<ContentRatingSystemT> ratingSystems_t = new ArrayList<>();
+
+ XmlUtils.beginDocument(parser, TAG_RATING_SYSTEM_DEFINITIONS);
+ final int outerDepth = parser.getDepth();
+ //Log.w(TAG, "loadFromXml_t,outerDepth:"+outerDepth);
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ // Log.w(TAG, "-----name:"+parser.getName());
+ if (parser.getName().equals(TAG_RATING_SYSTEM_DEFINITION)) {
+ ratingSystems_t.add(parseRatingSystemDefinition_t(parser));
+ }
+ }
+ return ratingSystems_t;
+ }
+ private ContentRatingSystemT parseRatingSystemDefinition_t(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ ContentRatingSystemT builder = new ContentRatingSystemT();
+ //builder.setDomain(domain);
+ final int outerDepth = parser.getDepth();
+ int i = 0;
+ //Log.w(TAG, " parseRatingSystemDefinition_t:"+outerDepth);
+ int attr_num = parser.getAttributeCount();
+ // Log.w(TAG, " attr_num:"+attr_num);
+
+ for (i = 0; i< attr_num; i++) {
+ String attr = parser.getAttributeName(i);
+ switch (attr) {
+ case ATTR_NAME:
+ //Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ builder.setName(parser.getAttributeValue(i));
+ break;
+ case ATTR_RATING:
+ //Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ builder.setRegion(StringToInt(parser.getAttributeValue(i)));
+ break;
+ case ATTR_COUNTRY:
+ // Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ builder.setCountry(parser.getAttributeValue(i));
+ break;
+ case ATTR_DIMENSION_ID:
+ // Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ break;
+ }
+ }
+
+
+ while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+ i = 0;
+ // Log.w(TAG, " ---tag:"+parser.getName()+"i:"+i);
+ if (parser.getName().equals(TAG_RATING_DEFINITION)) {
+ builder.addRatingBuilder(parseRatingDefinition_t(parser));
+ }
+ }
+ return builder;
+ }
+
+ private int StringToInt(String value) {
+ int getvalue = -1;
+ try {
+ getvalue = Integer.valueOf(value);
+ } catch (NumberFormatException e){
+ throw new NumberFormatException("string is not integer: " + value);
+ }
+ return getvalue;
+ }
+
+ private RatingDefinition parseRatingDefinition_t(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ RatingDefinition builder = new RatingDefinition();
+ //Log.w(TAG, " parseRatingDefinition_t:"+parser.getAttributeCount());
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ String attr = parser.getAttributeName(i);
+ switch (attr) {
+ /*case ATTR_NAME:
+ builder.setName(parser.getAttributeValue(i));
+ break;*/
+ case ATTR_TITLE:
+ case ATTR_NAME:
+ //Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ builder.setTitle(parser.getAttributeValue(i));
+ break;
+ case ATTR_DESCRIPTION:
+ // Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ builder.setDescription(parser.getAttributeValue(i));
+ break;
+ case ATTR_RADING_ID:
+ //Log.w(TAG, " attr:"+attr+", value:"+parser.getAttributeValue(i));
+ break;
+ }
+ }
+ return builder;
+ }
+
+ private void clearState() {
+ /*mBlockedRatings.clear();
+ mParentalControlsEnabled = false;*/
+ }
+
+ public class ContentRatingSystemT {
+ private String mName;
+ private String mCountry;
+ private int mRegion;
+ private final List<RatingDefinition> mRatings = new ArrayList<>();
+
+ public void ContentRatingSystemT(){
+ }
+
+ public void setName(String name) {
+ if (name == null || name.equals(""))
+ mName = "NULL";
+ else
+ mName = name;
+ }
+
+ public void setCountry(String country) {
+ if (country == null || country.equals(""))
+ mCountry = "NULL";
+ else
+ mCountry = country;
+ }
+
+ public void setRegion(int region) {
+ mRegion = region;
+ }
+
+ public int getRegion() {
+ return mRegion;
+ }
+
+ public String getName() {
+ return mName;
+ }
+ public String getCountry() {
+ return mCountry;
+ }
+ public void addRatingBuilder(RatingDefinition rating) {
+ if (mRatings == null) {
+ Log.d(TAG,"addRatingBuilder,mRating is NULL");
+ return;
+ }
+ mRatings.add(rating);
+ }
+ public List<RatingDefinition> getRatingDefinitions() {
+ return mRatings;
+ }
+ public String toString(){
+ String s = "Name:"+mName+",Country:" + mCountry + "\n RatingDefinition : \n";
+ for (RatingDefinition rating : mRatings)
+ s = s + rating.toString();
+ return s;
+ }
+
+ public void clear() {
+ mRatings.clear();
+ }
+ }
+
+ public class RatingDefinition {
+ private String mTitle;
+ private String mDescription;
+ public void RatingDefinition(){
+ }
+
+ public void setTitle(String name) {
+ if (name == null || name.equals(""))
+ mTitle = "NULL";
+ else
+ mTitle = name;
+ }
+ public void setDescription(String description) {
+ if (description == null || description.equals(""))
+ mDescription = "NULL";
+ else
+ mDescription = description;
+ }
+ public String getTitle() {
+ return mTitle;
+ }
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public String toString(){
+ String s = " Title:" + mTitle + ",Description:" + mDescription+"\n";
+ return s;
+ }
+ }
+} \ No newline at end of file
diff --git a/core/java/com/droidlogic/app/tv/DroidLogicOverlayView.java b/core/java/com/droidlogic/app/tv/DroidLogicOverlayView.java
index df00f1d..b3dd37e 100644
--- a/core/java/com/droidlogic/app/tv/DroidLogicOverlayView.java
+++ b/core/java/com/droidlogic/app/tv/DroidLogicOverlayView.java
@@ -11,9 +11,10 @@ import android.widget.TextView;
public abstract class DroidLogicOverlayView extends FrameLayout {
private static final String TAG = "DroidLogicOverlayView";
- protected ImageView mImageView;
- protected TextView mTextView;
- protected View mSubtitleView;
+ protected ImageView mImageView;
+ protected TextView mTextView;
+ protected View mSubtitleView;
+ protected TextView mEasTextView;
public DroidLogicOverlayView(Context context) {
this(context, null);
@@ -47,6 +48,14 @@ public abstract class DroidLogicOverlayView extends FrameLayout {
mTextView.setText(resId);
}
+ public void setTextForEas(CharSequence text){
+ mEasTextView.setText(text);
+ }
+
+ public void setEasTextVisibility(boolean visible) {
+ mEasTextView.setVisibility(visible ? VISIBLE : GONE);
+ }
+
public void setTextVisibility(boolean visible) {
mTextView.setVisibility(visible ? VISIBLE : GONE);
}
diff --git a/core/java/com/droidlogic/app/tv/DroidLogicTvInputService.java b/core/java/com/droidlogic/app/tv/DroidLogicTvInputService.java
index d1eec8c..0989cee 100644
--- a/core/java/com/droidlogic/app/tv/DroidLogicTvInputService.java
+++ b/core/java/com/droidlogic/app/tv/DroidLogicTvInputService.java
@@ -393,9 +393,11 @@ public class DroidLogicTvInputService extends TvInputService implements
public void onSigChanged(TVInSignalInfo signal_info) { }
+
@Override
public void StorDBonEvent(TvControlManager.ScannerEvent event) {
- mTvStoreManager.onStoreEvent(event);
+ if (mTvStoreManager != null)
+ mTvStoreManager.onStoreEvent(event);
}
public void resetScanStoreListener() {
@@ -478,6 +480,10 @@ public class DroidLogicTvInputService extends TvInputService implements
mSurface = null;
stopTvPlay(session.mId);
}
+
+ if (mHardware != null && mSurface != null && mSurface.isValid()) {
+ mHardware.setSurface(mSurface, mConfigs[0]);
+ }
}
public int doTune(Uri uri, int sessionId) {
@@ -501,7 +507,7 @@ public class DroidLogicTvInputService extends TvInputService implements
private int startTvPlay() {
Log.d(TAG, "startTvPlay inputId=" + mCurrentInputId + " surface=" + mSurface);
if (mHardware != null && mSurface != null && mSurface.isValid()) {
- mHardware.setSurface(mSurface, mConfigs[0]);
+ //mHardware.setSurface(mSurface, mConfigs[0]);
selectHdmiDevice(mDeviceId);
return ACTION_SUCCESS;
}
@@ -509,6 +515,7 @@ public class DroidLogicTvInputService extends TvInputService implements
}
private int stopTvPlay(int sessionId) {
+ Log.d(TAG, "stopTvPlay:"+sessionId+" mHardware:"+mHardware);
if (mHardware != null) {
mHardware.setSurface(null, mConfigs[0]);
tvPlayStopped(sessionId);
@@ -670,4 +677,13 @@ public class DroidLogicTvInputService extends TvInputService implements
private float getUptimeSeconds() {
return (float)SystemClock.uptimeMillis() / 1000;
}
+
+ public void notifyAppEasStatus(boolean isStarted){
+ Log.d(TAG, "notifyAppEasStatus:"+isStarted);
+ Bundle bundle = new Bundle();
+ bundle.putInt(DroidLogicTvUtils.SIG_INFO_EAS_STATUS, isStarted ? 1 : 0);
+ if (mSession != null) {
+ mSession.notifySessionEvent(DroidLogicTvUtils.SIG_INFO_EAS_EVENT, bundle);
+ }
+ }
}
diff --git a/core/java/com/droidlogic/app/tv/DroidLogicTvUtils.java b/core/java/com/droidlogic/app/tv/DroidLogicTvUtils.java
index 0a80335..4039133 100644
--- a/core/java/com/droidlogic/app/tv/DroidLogicTvUtils.java
+++ b/core/java/com/droidlogic/app/tv/DroidLogicTvUtils.java
@@ -105,6 +105,8 @@ public class DroidLogicTvUtils
public static final int SIG_INFO_TYPE_ADTV = 5;
public static final int SIG_INFO_TYPE_OTHER = 6;
+ public static final String SIG_INFO_EAS_EVENT = "dtv_eas_event";
+ public static final String SIG_INFO_EAS_STATUS = "eas_status";
/**
* source input type need to switch
*/
@@ -192,6 +194,13 @@ public class DroidLogicTvUtils
/*auto tracks call*/
public static final String ACTION_DTV_AUTO_TRACKS = "dtv_auto_tracks";
+ /*when it's on ,block all program without rating*/
+ public static final String ACTION_BLOCK_NORATING = "block_norating";
+ public static final String PARAM_NORATING_ENABLE = "enable_norating";
+ public static final int NORATING_OFF = 0;
+ public static final int NORATING_ON = 1;
+ public static final int NORATING_UNLOCK_CURRENT = 2;
+
/*set type call*/
public static final String ACTION_DTV_SET_TYPE = "dtv_set_type";
public static final String PARA_TYPE = "dtv_type";
@@ -224,6 +233,8 @@ public class DroidLogicTvUtils
public static final int OPEN_DEV_FOR_SCAN_DTV = 2;
public static final int CLOSE_DEV_FOR_SCAN = 3;
+ public static final String SYSTEM_CAPTION_STYLE_ENABLE = "accessibility_captioning_style_enabled";
+
/**
* used for TvSettings to switch hdmi source
* {@link #SOURCE_NAME}
@@ -248,10 +259,15 @@ public class DroidLogicTvUtils
public static final String TV_ATV_CHANNEL_INDEX = "tv_atv_channel_index";
public static final String TV_DTV_CHANNEL_INDEX = "tv_dtv_channel_index";
public static final String TV_CURRENT_CHANNEL_IS_RADIO = "tv_current_channel_is_radio";
+ public static final String BLOCK_NORATING = "block_norating";
public static final String TV_KEY_DTV_NUMBER_MODE = "tv_dtv_number_mode";
public static final String TV_KEY_DTV_TYPE = "tv_dtv_type";
+ public static final String SIGNAL_TYPE_ERROR = "error";
+ public static final String ALL_CHANNELS_NUMBER = "all_channels_number";
+ public static final String DTV_TYPE_SWITCHED = "dtv_type_switched";
+
private static final UriMatcher sUriMatcher;
public static final int NO_MATCH = UriMatcher.NO_MATCH;
public static final int MATCH_CHANNEL = 1;
@@ -274,6 +290,16 @@ public class DroidLogicTvUtils
sUriMatcher.addURI(TvContract.AUTHORITY, "watched_program/#", MATCH_WATCHED_PROGRAM_ID);
}
+ public static String getCurrentSignalType(Context context) {
+ String dtvType = Settings.System.getString(context.getContentResolver(), DroidLogicTvUtils.TV_KEY_DTV_TYPE);
+ if (dtvType == null) {
+ return DroidLogicTvUtils.SIGNAL_TYPE_ERROR;
+ } else {
+ Log.d(TAG, "getCurrentSignalType = " + dtvType);
+ return dtvType;
+ }
+ }
+
public static int matchsWhich(Uri uri) {
return sUriMatcher.match(uri);
}
@@ -688,9 +714,10 @@ public class DroidLogicTvUtils
"CA_TV_FR_E", "CA_TV_FR_G", "CA_TV_FR_8", "CA_TV_FR_13", "CA_TV_FR_16", "CA_TV_FR_18"
};
+
public static TvContentRating[] parseDRatings(String jsonString) {
String RatingDomain = "com.android.tv";
-
+ Log.d(TAG, "parseDRatings:"+jsonString);
if (jsonString == null || jsonString.isEmpty())
return null;
@@ -732,38 +759,38 @@ public class DroidLogicTvUtils
JSONArray ratings = g.optJSONArray("rx");
if (ratings != null) {
JSONObject ratingValues = ratings.optJSONObject(0);
+ if (null == ratingValues)
+ continue;
int dimension = ratingValues.optInt("d", -1);
int value = ratingValues.optInt("r", -1);
if (dimension == -1 || value == -1)
continue;
if (region == 1) {//US ratings
- if (dimension == 7
- /*&& ratingDescription != null
- && ratingDescription.startsWith("MPAA-")*/
- ) {
- TvContentRating r = TvContentRating.createRating(RatingDomain, "US_MV",
- DroidLogicTvUtils.US_ContentRatingDimensions[dimension][value]);
- RatingList.add(r);
- Log.d(TAG, "add rating:"+r.flattenToString());
- } else /*if (ratingDescription != null
- && ratingDescription.startsWith("TV-")
- )*/ {
- ArrayList<String> subRatings = new ArrayList<String>();
- for (int j = 1; j < ratings.length(); j++) {
- JSONObject subRatingValues = ratings.optJSONObject(j);
- int subDimension = subRatingValues.optInt("d", -1);
- int subValue = subRatingValues.optInt("r", -1);
- if (subDimension == -1 || subValue == -1)
- continue;
- subRatings.add(DroidLogicTvUtils.US_ContentRatingDimensions[subDimension][subValue]);
+ for (int j = 0; j < ratings.length(); j++) {
+ JSONObject subRatingValues = ratings.optJSONObject(j);
+ int subDimension = subRatingValues.optInt("d", -1);
+ int subValue = subRatingValues.optInt("r", -1);
+
+ if (subDimension == -1 || subValue == -1)
+ continue;
+ if (subDimension > 7 ||
+ subValue >= DroidLogicTvUtils.US_ContentRatingDimensions[subDimension].length ||
+ TextUtils.isEmpty(DroidLogicTvUtils.US_ContentRatingDimensions[subDimension][subValue])) {
+ continue;
+ }
+ if (subDimension == 7) {
+ TvContentRating r = TvContentRating.createRating(RatingDomain, "US_MV",
+ DroidLogicTvUtils.US_ContentRatingDimensions[subDimension][subValue]);
+ RatingList.add(r);
+ Log.d(TAG, "mv add rating:"+r.flattenToString());
+ } else {
+ if (subDimension == 255)
+ subDimension = 0;
+ TvContentRating r = TvContentRating.createRating(RatingDomain, "US_TV",
+ DroidLogicTvUtils.US_ContentRatingDimensions[subDimension][subValue]);
+ RatingList.add(r);
+ Log.d(TAG, "tv add rating:"+r.flattenToString());
}
- if (dimension == 255)
- dimension = 0;
- TvContentRating r = TvContentRating.createRating(RatingDomain, "US_TV",
- DroidLogicTvUtils.US_ContentRatingDimensions[dimension][value],
- subRatings.toArray(new String[subRatings.size()]));
- RatingList.add(r);
- Log.d(TAG, "add rating:"+r.flattenToString());
}
} else if (region == 2) {//Canadian ratings
for (int j = 0; j < ratings.length(); j++) {
@@ -773,12 +800,20 @@ public class DroidLogicTvUtils
if (Dimension == -1 || Value == -1)
continue;
if (Dimension == 0) {
+ if (Value >= DroidLogicTvUtils.CA_EN_ContentRatingDimensions.length ||
+ TextUtils.isEmpty(DroidLogicTvUtils.CA_EN_ContentRatingDimensions[Value])) {
+ continue;
+ }
//canadian english language rating
TvContentRating r = TvContentRating.createRating(RatingDomain, "CA_TV_EN",
DroidLogicTvUtils.CA_EN_ContentRatingDimensions[Value]);
RatingList.add(r);
Log.d(TAG, "add rating:"+r.flattenToString());
} else if (Dimension == 1) {
+ if (Value >= DroidLogicTvUtils.CA_FR_ContentRatingDimensions.length ||
+ TextUtils.isEmpty(DroidLogicTvUtils.CA_FR_ContentRatingDimensions[Value])) {
+ continue;
+ }
//canadian frech language rating
TvContentRating r = TvContentRating.createRating(RatingDomain, "CA_TV_FR",
DroidLogicTvUtils.CA_FR_ContentRatingDimensions[Value]);
@@ -829,7 +864,7 @@ public class DroidLogicTvUtils
if ((dlsv & VBI_RATING_S) == VBI_RATING_S)
subRatings.add("US_TV_S");
if ((dlsv & VBI_RATING_V) == VBI_RATING_V)
- subRatings.add("US_TV_V");
+ subRatings.add(TextUtils.equals(ratings[auth][id], "US_TV_Y7")? "US_TV_FV" : "US_TV_V");
return TvContentRating.createRating(RatingDomain, region[auth],
ratings[auth][id],
diff --git a/core/java/com/droidlogic/app/tv/EasEvent.java b/core/java/com/droidlogic/app/tv/EasEvent.java
new file mode 100644
index 0000000..e32d140
--- a/dev/null
+++ b/core/java/com/droidlogic/app/tv/EasEvent.java
@@ -0,0 +1,152 @@
+package com.droidlogic.app.tv;
+
+import android.os.Parcel;
+import android.util.Log;
+
+public class EasEvent {
+ private static final String TAG = "EasEvent";
+ public int tableId; //table id
+ public int extension; //subtable id
+ public int version; //version_number
+ public int currentNext; //current_next_indicator
+ public int sequenceNum; //sequence version
+ public int protocolVersion; //protocol version
+ public int easEventId; //eas event id
+ public int[] easOrigCode; //eas event orig code
+ public int easEventCodeLen; //eas event code len
+ public int[] easEventCode; //eas event code
+ public int alertMessageTimeRemaining; //alert msg remain time
+ public int eventStartTime; //eas event start time
+ public int eventDuration; //event dur
+ public int alertPriority; //alert priority
+ public int detailsOOBSourceID; //details oob source id
+ public int detailsMajorChannelNumber; //details major channel num
+ public int detailsMinorChannelNumber; //details minor channel num
+ public int audioOOBSourceID; //audio oob source id
+ public int locationCount; //location count
+ public Location[] location; //location info
+ public int exceptionCount; //exception count
+ public ExceptionList[] exceptionList; //exception info
+ public int multiTextCount; //multi_text count
+ public MultiStr[] multiText; //nature and alert multi str information structure.
+ public int descriptorTextCount; //descriptor text count.
+ public Descriptor[] descriptor; //descriptor structure.
+
+ public class Location {
+ public int stateCode;
+ public int countySubdiv;
+ public int countyCode;
+ }
+ public class ExceptionList {
+ public int inBandRefer;
+ public int exceptionMajorChannelNumber; //the exception major channel num
+ public int exceptionMinorChannelNumber; //the exception minor channel num
+ public int exceptionOOBSourceID; //the exception oob source id
+ }
+ public class MultiStr {
+ public int[] lang; //the language of mlti str
+ public int type; //the str type, alert or nature
+ public int compressionType; //compression type
+ public int mode; //mode
+ public int numberBytes; //number bytes
+ public int[] compressedStr; //the compressed str
+ }
+ public class Descriptor {
+ public int tag; //descriptor_tag
+ public int length; //descriptor_length
+ public int[] data; //content
+ }
+
+ public void printEasEventInfo(){
+ Log.i(TAG,"[EasEventInfo]"+
+ "\n alertMessageTimeRemaining = "+alertMessageTimeRemaining+
+ "\n alertPriority = "+alertPriority+
+ "\n detailsMajorChannelNumber = "+detailsMajorChannelNumber+
+ "\n detailsMinorChannelNumber = "+detailsMinorChannelNumber);
+ }
+
+ public void readEasEvent(Parcel p) {
+ Log.i(TAG,"readEasEvent");
+ int i, j, k;
+ tableId = p.readInt();
+ extension = p.readInt();
+ version = p.readInt();
+ currentNext = p.readInt();
+ sequenceNum = p.readInt();
+ protocolVersion = p.readInt();
+ easEventId = p.readInt();
+ easOrigCode = new int[3];
+ for (j=0;j<3;j++) {
+ easOrigCode[j] = p.readInt();
+ }
+ easEventCodeLen = p.readInt();
+ if (easEventCodeLen != 0) {
+ easEventCode = new int[easEventCodeLen];
+ for (j=0;j<easEventCodeLen;j++)
+ easEventCode[j] = p.readInt();
+ }
+ alertMessageTimeRemaining = p.readInt();
+ eventStartTime = p.readInt();
+ eventDuration = p.readInt();
+ alertPriority = p.readInt();
+ detailsOOBSourceID = p.readInt();
+ detailsMajorChannelNumber = p.readInt();
+ detailsMinorChannelNumber = p.readInt();
+ audioOOBSourceID = p.readInt();
+ locationCount = p.readInt();
+ if (locationCount != 0) {
+ location = new Location[locationCount];
+ for (j=0;j<locationCount;j++) {
+ location[j] = new Location();
+ location[j].stateCode = p.readInt();
+ location[j].countySubdiv = p.readInt();
+ location[j].countyCode = p.readInt();
+ }
+ }
+ exceptionCount = p.readInt();
+ if (exceptionCount != 0) {
+ exceptionList = new ExceptionList[exceptionCount];
+ for (j=0;j<exceptionCount;j++) {
+ exceptionList[j] = new ExceptionList();
+ exceptionList[j].inBandRefer = p.readInt();
+ exceptionList[j].exceptionMajorChannelNumber = p.readInt();
+ exceptionList[j].exceptionMinorChannelNumber = p.readInt();
+ exceptionList[j].exceptionOOBSourceID = p.readInt();
+ }
+ }
+ multiTextCount = p.readInt();
+ if (multiTextCount != 0) {
+ multiText = new MultiStr[multiTextCount];
+ for (j=0;j<multiTextCount;j++) {
+ multiText[j] = new MultiStr();
+ multiText[j].lang = new int[3];
+ multiText[j].lang[0] = p.readInt();
+ multiText[j].lang[1] = p.readInt();
+ multiText[j].lang[2] = p.readInt();
+ multiText[j].type = p.readInt();
+ multiText[j].compressionType = p.readInt();
+ multiText[j].mode = p.readInt();
+ multiText[j].numberBytes = p.readInt();
+ multiText[j].compressedStr = new int[multiText[j].numberBytes];
+ for (k=0;k<multiText[j].numberBytes;k++) {
+ multiText[j].compressedStr[k] = p.readInt();
+ }
+ }
+ }
+ descriptorTextCount = p.readInt();
+ if (descriptorTextCount != 0) {
+ descriptor = new Descriptor[descriptorTextCount];
+ for (j=0;j<descriptorTextCount;j++) {
+ descriptor[j] = new Descriptor();
+ descriptor[j].tag = p.readInt();
+ descriptor[j].length = p.readInt();
+ descriptor[j].data = new int[descriptor[j].length];
+ for (k=0;k<descriptor[j].length;k++) {
+ descriptor[j].data[k] = p.readInt();
+ }
+ }
+ }
+
+ }
+ }
+
diff --git a/core/java/com/droidlogic/app/tv/EasManager.java b/core/java/com/droidlogic/app/tv/EasManager.java
new file mode 100644
index 0000000..236d630
--- a/dev/null
+++ b/core/java/com/droidlogic/app/tv/EasManager.java
@@ -0,0 +1,33 @@
+package com.droidlogic.app.tv;
+
+import android.os.Parcel;
+import android.util.Log;
+
+public class EasManager {
+ private static final String TAG = "EasManager";
+ private static final long GPS_UTC_OFFSET_IN_SECONDS = 315964800;
+ private static final int EAS_TEXT_MESSAGE = 0;
+ private static final int EAS_LOW_PRIORITY = 4;
+ private static final int EAS_MEDIUM_PRIORITY = 8;
+ private static final int EAS_HIGH_PRIORITY = 12;
+
+ private EasEvent preEasEvent = null;
+ private EasEvent curEasEvent = null;
+
+ public boolean isEasEventNeedProcess(EasEvent easEvent) {
+ Log.i(TAG,"isEasEventNeedProcess");
+ curEasEvent = easEvent;
+ easEvent.printEasEventInfo();
+ if (easEvent.protocolVersion != 0) {
+ return false;
+ }
+
+ if (easEvent.alertPriority == EAS_TEXT_MESSAGE) {
+ return false;
+ }
+
+ preEasEvent = easEvent;
+ return true;
+ }
+ }
+
diff --git a/core/java/com/droidlogic/app/tv/Program.java b/core/java/com/droidlogic/app/tv/Program.java
index 0e32f6d..cf5287a 100644
--- a/core/java/com/droidlogic/app/tv/Program.java
+++ b/core/java/com/droidlogic/app/tv/Program.java
@@ -13,8 +13,8 @@ import java.util.Objects;
* A convenience class to create and insert program information into the database.
*/
public final class Program implements Comparable<Program> {
- private static final long INVALID_LONG_VALUE = -1;
- private static final int INVALID_INT_VALUE = -1;
+ public static final long INVALID_LONG_VALUE = -1;
+ public static final int INVALID_INT_VALUE = -1;
private long mId;
private long mChannelId;
@@ -35,6 +35,8 @@ public final class Program implements Comparable<Program> {
private TvContentRating[] mContentRatings;
private String mInternalProviderData;
private boolean mIsAppointed;
+ private String mVersion;
+ private String mEitExt;
private Program() {
mId = INVALID_LONG_VALUE;
@@ -47,6 +49,8 @@ public final class Program implements Comparable<Program> {
mVideoWidth = INVALID_INT_VALUE;
mVideoHeight = INVALID_INT_VALUE;
mIsAppointed = false;
+ mVersion = null;
+ mEitExt = null;
}
public long getId() {
@@ -109,6 +113,10 @@ public final class Program implements Comparable<Program> {
return mContentRatings;
}
+ public void setContentRatings(TvContentRating[] rating) {
+ mContentRatings = rating;
+ }
+
public String getPosterArtUri() {
return mPosterArtUri;
}
@@ -134,6 +142,22 @@ public final class Program implements Comparable<Program> {
mIsAppointed = isAppointed;
}
+ public String getVersion() {
+ return mVersion;
+ }
+
+ public void setVersion(String version) {
+ mVersion = version;
+ }
+
+ public String getEitExt() {
+ return mEitExt;
+ }
+
+ public void setEitExt(String ext) {
+ mEitExt = ext;
+ }
+
@Override
public int hashCode() {
return Objects.hash(mChannelId, mStartTimeUtcMillis, mEndTimeUtcMillis,
@@ -162,7 +186,9 @@ public final class Program implements Comparable<Program> {
&& Arrays.equals(mContentRatings, program.mContentRatings)
&& Arrays.equals(mCanonicalGenres, program.mCanonicalGenres)
&& mSeasonNumber == program.mSeasonNumber
- && mEpisodeNumber == program.mEpisodeNumber;
+ && mEpisodeNumber == program.mEpisodeNumber
+ && TextUtils.equals(mVersion, program.mVersion)
+ && TextUtils.equals(mEitExt, program.mEitExt);
}
public boolean matchsWithoutDescription(Program program) {
@@ -178,7 +204,9 @@ public final class Program implements Comparable<Program> {
&& Arrays.equals(mContentRatings, program.mContentRatings)
&& Arrays.equals(mCanonicalGenres, program.mCanonicalGenres)
&& mSeasonNumber == program.mSeasonNumber
- && mEpisodeNumber == program.mEpisodeNumber;
+ && mEpisodeNumber == program.mEpisodeNumber
+ && Objects.equals(contentRatingsToString(mContentRatings),
+ contentRatingsToString(program.mContentRatings));
}
@Override
@@ -206,7 +234,8 @@ public final class Program implements Comparable<Program> {
.append(", thumbnailUri=").append(mThumbnailUri)
.append(", contentRatings=").append(mContentRatings)
.append(", genres=").append(mCanonicalGenres)
- .append(", isAppointed=").append(mIsAppointed);
+ .append(", isAppointed=").append(mIsAppointed)
+ .append(", ext=").append(mVersion).append(":"+mEitExt);
return builder.append("}").toString();
}
@@ -232,6 +261,8 @@ public final class Program implements Comparable<Program> {
mCanonicalGenres = other.mCanonicalGenres;
mContentRatings = other.mContentRatings;
mIsAppointed = other.mIsAppointed;
+ mVersion = other.mVersion;
+ mEitExt = other.mEitExt;
}
public ContentValues toContentValues() {
@@ -315,6 +346,16 @@ public final class Program implements Comparable<Program> {
}
values.put(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG1, mIsAppointed ? 1 : 0);
values.put(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG2, mProgramId);
+ if (!TextUtils.isEmpty(mVersion)) {
+ values.put(TvContract.Programs.COLUMN_VERSION_NUMBER, mVersion);
+ } else {
+ values.putNull(TvContract.Programs.COLUMN_VERSION_NUMBER);
+ }
+ if (!TextUtils.isEmpty(mEitExt)) {
+ values.put(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG3, mEitExt);
+ } else {
+ values.putNull(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ }
return values;
}
@@ -397,6 +438,14 @@ public final class Program implements Comparable<Program> {
if (index >= 0) {
builder.setProgramId(cursor.getInt(index));
}
+ index = cursor.getColumnIndex(TvContract.Programs.COLUMN_VERSION_NUMBER);
+ if (index >= 0 && !cursor.isNull(index)) {
+ builder.setVersion(cursor.getString(index));
+ }
+ index = cursor.getColumnIndex(TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG3);
+ if (index >=0 && !cursor.isNull(index)) {
+ builder.setEitExt(cursor.getString(index));
+ }
return builder.build();
}
@@ -506,6 +555,17 @@ public final class Program implements Comparable<Program> {
mProgram.mIsAppointed = isAppointed;
return this;
}
+
+ public Builder setVersion(String version) {
+ mProgram.mVersion = version;
+ return this;
+ }
+
+ public Builder setEitExt(String ext) {
+ mProgram.mEitExt = ext;
+ return this;
+ }
+
public Program build() {
return mProgram;
}
diff --git a/core/java/com/droidlogic/app/tv/TVTime.java b/core/java/com/droidlogic/app/tv/TVTime.java
index dd723c9..a91d01b 100644
--- a/core/java/com/droidlogic/app/tv/TVTime.java
+++ b/core/java/com/droidlogic/app/tv/TVTime.java
@@ -3,11 +3,12 @@ package com.droidlogic.app.tv;
import android.content.Context;
import android.provider.Settings;
import android.os.SystemClock;
+import android.util.Log;
import java.util.Date;
import com.droidlogic.app.SystemControlManager;
-
+import com.droidlogic.app.DaylightSavingTime;
/**
*TV时间管理
*/
@@ -39,6 +40,10 @@ public class TVTime{
&& (Math.abs(diff) > 1000)) {
SystemClock.setCurrentTimeMillis(time);
diff = 0;
+ DaylightSavingTime daylightSavingTime = DaylightSavingTime.getInstance();
+ daylightSavingTime.updateDaylightSavingTimeForce();
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0);
+ Log.d("DroidLogic", "setTime");
}
Settings.System.putLong(mContext.getContentResolver(), TV_KEY_TVTIME, diff);
diff --git a/core/java/com/droidlogic/app/tv/TvControlCommand.java b/core/java/com/droidlogic/app/tv/TvControlCommand.java
index 6440f04..0709a88 100644
--- a/core/java/com/droidlogic/app/tv/TvControlCommand.java
+++ b/core/java/com/droidlogic/app/tv/TvControlCommand.java
@@ -254,7 +254,11 @@ public interface TvControlCommand {
int EPG_EVENT_CALLBACK = 542;
int VFRAME_BMP_EVENT_CALLBACK = 543;
int SCANNING_FRAME_STABLE_CALLBACK = 544;
- int SCAN_LCN_CALLBACK = 545;
+ int FRONTEND_EVENT_CALLBACK = 545;
+ int RECORDER_EVENT_CALLBACK = 546;
+ int SCAN_LCN_CALLBACK = 547;
+ int RRT_EVENT_CALLBACK = 548;
+ int EAS_EVENT_CALLBACK = 549;
// CALLBACK END
// SSM
@@ -484,6 +488,7 @@ public interface TvControlCommand {
int START_AUTO_BACKLIGHT = 1456;
int STOP_AUTO_BACKLIGHT = 1457;
int IS_AUTO_BACKLIGHTING = 1458;
+ int HDMIAV_HOTPLUGDETECT_ONOFF = 1459;
int GET_AVERAGE_LUMA = 1480;
int GET_AUTO_BACKLIGHT_DATA = 1481;
@@ -494,4 +499,16 @@ public interface TvControlCommand {
int TV_SET_FRONTEND = 1486;
int SET_AUDIO_OUTMODE = 1501;
int GET_AUDIO_OUTMODE = 1502;
+ int GET_AUDIO_STREAM_OUTMODE = 1503;
+
+ int SET_AMAUDIO_VOLUME = 1504;
+ int GET_AMAUDIO_VOLUME = 1505;
+ int SAVE_AMAUDIO_VOLUME = 1506;
+ int GET_SAVE_AMAUDIO_VOLUME = 1507;
+ int DTV_UPDATE_RRT = 1508;
+ int DTV_SEARCH_RRT = 1509;
+ int DTV_UPDATE_EAS = 1510;
+
+ int DTV_RECORDING_CMD = 1600;
+ int DTV_PLAY_CMD = 1610;
}
diff --git a/core/java/com/droidlogic/app/tv/TvControlManager.java b/core/java/com/droidlogic/app/tv/TvControlManager.java
index f741813..0749ae0 100644
--- a/core/java/com/droidlogic/app/tv/TvControlManager.java
+++ b/core/java/com/droidlogic/app/tv/TvControlManager.java
@@ -43,6 +43,7 @@ import android.text.TextUtils;
//import android.media.audiofx.Hpeq;
import static com.droidlogic.app.tv.TvControlCommand.*;
+import com.droidlogic.app.tv.EasEvent;
public class TvControlManager {
private static final String TAG = "TvControlManager";
@@ -116,8 +117,15 @@ public class TvControlManager {
private ScanningFrameStableListener mScanningFrameStableListener = null;
private VframBMPEventListener mVframBMPListener = null;
private EpgEventListener mEpgListener = null;
+ private RRT5SourceUpdateListener mRrtListener = null;
private AVPlaybackListener mAVPlaybackListener = null;
+ private EasEventListener mEasListener = null;
+ private int rrt5XmlLoadStatus = 0;
+ public static int EVENT_RRT_SCAN_START = 1;
+ public static int EVENT_RRT_SCAN_END = 3;
+
+ private EasManager easManager = new EasManager();
private static TvControlManager mInstance;
private native final void native_setup(Object tv_this);
@@ -221,6 +229,26 @@ public class TvControlManager {
return ret;
}
+ public int sendCmdStringArray(int cmd, int id, String[] values) {
+ libtv_log_open();
+ Parcel request = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ request.writeInt(cmd);
+ request.writeInt(id);
+
+ for (int i = 0; i < values.length; i++) {
+ request.writeString(values[i]);
+ }
+ request.setDataPosition(0);
+ processCmd(request, reply);
+ reply.setDataPosition(0);
+ int ret = reply.readInt();
+
+ request.recycle();
+ reply.recycle();
+ return ret;
+ }
+
class EventHandler extends Handler {
int dataArray[];
int cmdArray[];
@@ -326,6 +354,7 @@ public class TvControlManager {
scan_ev.accessControlled = p.readInt();
scan_ev.hidden = p.readInt();
scan_ev.hideGuide = p.readInt();
+ scan_ev.vct = p.readString();
}
@Override
@@ -502,9 +531,48 @@ public class TvControlManager {
mCloseCaptionListener.onCloseCaptionProcess(dataArray, cmdArray);
}
break;
- default:
- Log.e(TAG, "Unknown message type " + msg.what);
+
+ case RECORDER_EVENT_CALLBACK:
+ p = ((Parcel) (msg.obj));
+ if (mRecorderEventListener != null) {
+ RecorderEvent ev = new RecorderEvent();
+ ev.Id = p.readString();
+ ev.Status = p.readInt();
+ ev.Error = p.readInt();
+ mRecorderEventListener.onRecoderEvent(ev);
+ }
break;
+
+ case RRT_EVENT_CALLBACK:
+ p = ((Parcel) (msg.obj));
+ if (mRrtListener != null) {
+ int result = p.readInt();
+ Log.e(TAG, "RRT_EVENT_CALLBACK:" + result);
+ rrt5XmlLoadStatus = result;
+ mRrtListener.onRRT5InfoUpdated(result);
+ }
+ break;
+
+ case EAS_EVENT_CALLBACK:
+ Log.i(TAG,"get EAS_event_callBack");
+ p = ((Parcel) (msg.obj));
+ if (mEasListener != null) {
+ Log.i(TAG,"mEaslister is not null");
+ int sectionCount = p.readInt();
+ Log.i(TAG,"eas section count = "+sectionCount);
+ for (int count = 0; count<sectionCount; count++) {
+ EasEvent curEasEvent = new EasEvent();
+ curEasEvent.readEasEvent(p);
+ if (easManager.isEasEventNeedProcess(curEasEvent)) {
+ mEasListener.processDetailsChannelAlert(curEasEvent);
+ }
+ }
+ }
+
+ break;
+ default:
+ Log.e(TAG, "Unknown message type " + msg.what);
+ break;
}
}
}
@@ -629,6 +697,17 @@ public class TvControlManager {
}
/**
+ * @Function: GetHotPlugDetect
+ * @Description: Get hotplug detect enable status
+ * @Param:
+ * @Return: true refer to on, and false refers to off
+ */
+ public boolean GetHotPlugDetectEnableStatus() {
+ int ret = sendCmd(HDMIAV_HOTPLUGDETECT_ONOFF);
+ return (ret == 1 ? true:false);
+ }
+
+ /**
* @Function: GetLastSourceInput
* @Description: Get last source input
* @Param:
@@ -1245,6 +1324,52 @@ public class TvControlManager {
return sendCmd(GET_AUDIO_OUTMODE);
}
+ public int GetAudioStreamOutmode(){
+ return sendCmd(GET_AUDIO_STREAM_OUTMODE);
+ }
+
+ public static final int AM_AUDIO_TV = 0;
+ public static final int AM_AUDIO_AV1 = 1;
+ public static final int AM_AUDIO_AV2 = 2;
+ public static final int AM_AUDIO_YPBPR1 = 3;
+ public static final int AM_AUDIO_YPBPR2 = 4;
+ public static final int AM_AUDIO_HDMI1 = 5;
+ public static final int AM_AUDIO_HDMI2 = 6;
+ public static final int AM_AUDIO_HDMI3 = 7;
+ public static final int AM_AUDIO_HDMI4 = 8;
+ public static final int AM_AUDIO_VGA = 9;
+ public static final int AM_AUDIO_MPEG = 10;
+ public static final int AM_AUDIO_DTV = 11;
+ public static final int AM_AUDIO_SVIDEO = 12;
+ public static final int AM_AUDIO_IPTV = 13;
+ public static final int AM_AUDIO_DUMMY = 14;
+ public static final int AM_AUDIO_SPDIF = 15;
+ public static final int AM_AUDIO_ADTV = 16;
+
+ public int SetAmAudioVolume(int volume, int source) {
+ int val[] = new int[]{volume};
+ if (source == AM_AUDIO_MPEG) {
+ SystemProperties.set("persist.media.player.volume",
+ String.valueOf(volume));
+ }
+
+ return sendCmdIntArray(SET_AMAUDIO_VOLUME, val);
+ }
+
+ public int GetAmAudioVolume() {
+ return sendCmd(GET_AMAUDIO_VOLUME);
+ }
+
+ public int SaveAmAudioVolume(int volume, int source) {
+ int val[] = new int[]{volume, source};
+ return sendCmdIntArray(SAVE_AMAUDIO_VOLUME, val);
+ }
+
+ public int GetSaveAmAudioVolume(int source) {
+ int val[] = new int[]{source};
+ return sendCmdIntArray(GET_SAVE_AMAUDIO_VOLUME, val);
+ }
+
public enum Noise_Reduction_Mode {
REDUCE_NOISE_CLOSE(0),
REDUCE_NOISE_WEAK(1),
@@ -4248,11 +4373,13 @@ public class TvControlManager {
base = r.readInt() - 1;
bpl.ID = 1 ;
bpl.freq= r.readInt();
+ bpl.channelNum = r.readInt();
FList.add(bpl);
for (int i = 1; i < size; i++) {
FreqList pl = new FreqList();
pl.ID = r.readInt() - base;
pl.freq= r.readInt();
+ pl.channelNum = r.readInt();
FList.add(pl);
}
cmd.recycle();
@@ -4274,11 +4401,13 @@ public class TvControlManager {
base = r.readInt() - 1;
bpl.ID = 1 ;
bpl.freq= r.readInt();
+ bpl.channelNum = r.readInt();
FList.add(bpl);
for (int i = 1; i < size; i++) {
FreqList pl = new FreqList();
pl.ID = r.readInt() - base;
pl.freq= r.readInt();
+ pl.channelNum = r.readInt();
FList.add(pl);
}
cmd.recycle();
@@ -4446,6 +4575,7 @@ public class TvControlManager {
public int accessControlled;
public int hidden;
public int hideGuide;
+ public String vct;
}
public class ScannerLcnInfo {
@@ -4457,7 +4587,6 @@ public class TvControlManager {
public int[] valid;
}
-
public static class ScanMode {
private int scanMode;
@@ -4561,6 +4690,75 @@ public class TvControlManager {
void onEvent(EpgEvent ev);
}
+ //rrt
+ public void SetRRT5SourceUpdateListener(RRT5SourceUpdateListener l) {
+ mRrtListener = l;
+ }
+
+ public interface RRT5SourceUpdateListener {
+ void onRRT5InfoUpdated(int status);
+ }
+
+ public int updateRRTRes(int freq, int module, int mode) {
+ if (rrt5XmlLoadStatus == EVENT_RRT_SCAN_START) {
+ Log.d(TAG, "abandon updateRRTRes,becasue current status is : " + rrt5XmlLoadStatus);
+ return -1;
+ }
+ Log.d(TAG, "updateRRTRes,freq: " + freq+",module:"+module+",mode:"+mode);
+ int val[] = new int[]{freq, module, mode};
+ rrt5XmlLoadStatus = EVENT_RRT_SCAN_START;
+ return sendCmdIntArray(DTV_UPDATE_RRT, val);
+ }
+
+ public class RrtSearchInfo {
+ public String rating_region_name;
+ public String dimensions_name;
+ public String rating_value_text;
+ }
+
+ public RrtSearchInfo SearchRrtInfo(int rating_region_id, int dimension_id, int value_id) {
+ Parcel cmd = Parcel.obtain();
+ Parcel r = Parcel.obtain();
+ Log.d(TAG, "rating_region_id: " + rating_region_id);
+ Log.d(TAG, "dimension_id: " + dimension_id);
+ Log.d(TAG, "value_id: " + value_id);
+ cmd.writeInt(DTV_SEARCH_RRT);
+ cmd.writeInt(rating_region_id);
+ cmd.writeInt(dimension_id);
+ cmd.writeInt(value_id);
+ sendCmdToTv(cmd, r);
+
+ RrtSearchInfo tmpRet = new RrtSearchInfo();
+ int cnt = r.readInt();
+ if (cnt != 0) {
+ tmpRet.dimensions_name = r.readString();
+ }
+
+ cnt = r.readInt();
+ if (cnt != 0) {
+ tmpRet.rating_region_name = r.readString();
+ }
+
+ cnt = r.readInt();
+ if (cnt != 0) {
+ tmpRet.rating_value_text = r.readString();
+ }
+ cmd.recycle();
+ r.recycle();
+
+ Log.d(TAG, "rating_region_name: " + tmpRet.dimensions_name);
+ Log.d(TAG, "dimensions_name: " + tmpRet.rating_region_name);
+ Log.d(TAG, "rating_value_text: " + tmpRet.rating_value_text);
+ return tmpRet;
+ }
+
+ public void setEasListener(EasEventListener l) {
+ mEasListener = l;
+ }
+ public interface EasEventListener {
+ void processDetailsChannelAlert(EasEvent ev);
+ }
+
public class VFrameEvent{
public int FrameNum;
public int FrameSize;
@@ -5427,6 +5625,7 @@ public class TvControlManager {
public class FreqList {
public int ID;
public int freq;
+ public int channelNum;
}
/**
@@ -6153,6 +6352,10 @@ public class TvControlManager {
public final static int EVENT_AV_SCRAMBLED = 3;
public final static int EVENT_AV_UNSUPPORT = 4;
public final static int EVENT_AV_VIDEO_AVAILABLE = 5;
+ public final static int EVENT_AV_TIMESHIFT_REC_FAIL = 6;
+ public final static int EVENT_AV_TIMESHIFT_PLAY_FAIL = 7;
+ public final static int EVENT_AV_TIMESHIFT_START_TIME_CHANGED = 8;
+ public final static int EVENT_AV_TIMESHIFT_CURRENT_TIME_CHANGED = 9;
public final static int AUDIO_UNMUTE_FOR_TV = 0;
public final static int AUDIO_MUTE_FOR_TV = 1;
@@ -6473,5 +6676,87 @@ public class TvControlManager {
r.recycle();
return ret;
}
+
+ // frontend event
+ public class RecorderEvent {
+ //frontend events
+ public static final int EVENT_RECORDER_START = 1;
+ public static final int EVENT_RECORDER_STOP = 2;
+
+ public int Status;
+ public int Error;
+ public String Id;
+ }
+ public interface RecorderEventListener {
+ void onRecoderEvent(RecorderEvent ev);
+ };
+
+ private RecorderEventListener mRecorderEventListener = null;
+ public void SetRecorderEventListener(RecorderEventListener l) {
+ libtv_log_open();
+ mRecorderEventListener = l;
+ }
+
+
+ public static final int RECORDING_CMD_STOP = 0;
+ public static final int RECORDING_CMD_PREPARE = 1;
+ public static final int RECORDING_CMD_START = 2;
+
+ public int sendRecordingCmd(int cmd, String id, String param) {
+ String para[] = new String[]{id, param};
+ return sendCmdStringArray(DTV_RECORDING_CMD, cmd, para);
+ }
+
+ public int prepareRecording(String id, String param) {
+ return sendRecordingCmd(RECORDING_CMD_PREPARE, id, param);
+ }
+
+ public int startRecording(String id, String param) {
+ return sendRecordingCmd(RECORDING_CMD_START, id, param);
+ }
+
+ public int stopRecording(String id, String param) {
+ return sendRecordingCmd(RECORDING_CMD_STOP, id, param);
+ }
+
+ public static final int PLAY_CMD_STOP = 0;
+ public static final int PLAY_CMD_START = 1;
+ public static final int PLAY_CMD_PAUSE = 2;
+ public static final int PLAY_CMD_RESUME = 3;
+ public static final int PLAY_CMD_SEEK = 4;
+ public static final int PLAY_CMD_SETPARAM = 5;
+
+ public int sendPlayCmd(int cmd, String id, String param) {
+ String para[] = new String[]{id, param};
+ return sendCmdStringArray(DTV_PLAY_CMD, cmd, para);
+ }
+
+ public int startPlay(String id, String param) {
+ //SystemProperties.set ("media.audio.enable_asso", (adPrepare)? "1" : "0");
+ //SystemProperties.set ("media.audio.mix_asso", String.valueOf(adMixingLevel));
+ return sendPlayCmd(PLAY_CMD_START, id, param);
+ }
+
+ public int stopPlay(String id, String param) {
+ return sendPlayCmd(PLAY_CMD_STOP, id, param);
+ }
+
+ public int pausePlay(String id) {
+ return sendPlayCmd(PLAY_CMD_PAUSE, id, null);
+ }
+
+ public int resumePlay(String id) {
+ return sendPlayCmd(PLAY_CMD_RESUME, id, null);
+ }
+
+ public int seekPlay(String id, String param) {
+ return sendPlayCmd(PLAY_CMD_SEEK, id, param);
+ }
+
+ public int setPlayParam(String id, String param) {
+ return sendPlayCmd(PLAY_CMD_SETPARAM, id, param);
+ }
+
+
}
diff --git a/core/java/com/droidlogic/app/tv/TvDataBaseManager.java b/core/java/com/droidlogic/app/tv/TvDataBaseManager.java
index 193281b..b8ee7d7 100644
--- a/core/java/com/droidlogic/app/tv/TvDataBaseManager.java
+++ b/core/java/com/droidlogic/app/tv/TvDataBaseManager.java
@@ -32,6 +32,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
+import java.util.Objects;
import com.droidlogic.app.tv.DroidLogicTvUtils.*;
@@ -426,6 +427,10 @@ public class TvDataBaseManager {
map.put(ChannelInfo.KEY_ACCESS_CONTROL, String.valueOf(channel.getAccessControled()));
map.put(ChannelInfo.KEY_HIDDEN, String.valueOf(channel.getHidden()));
map.put(ChannelInfo.KEY_HIDE_GUIDE, String.valueOf(channel.getHideGuide()));
+ map.put(ChannelInfo.KEY_CONTENT_RATINGS, DroidLogicTvUtils.TvString.toString(channel.getContentRatings()));
+ map.put(ChannelInfo.KEY_SIGNAL_TYPE, DroidLogicTvUtils.TvString.toString(channel.getSignalType()));
+ map.put(ChannelInfo.KEY_VCT, "\""+channel.getVct()+"\"");
+ map.put(ChannelInfo.KEY_EITV, Arrays.toString(channel.getEitVersions()));
String output = DroidLogicTvUtils.mapToJson(map);
values.put(TvContract.Channels.COLUMN_INTERNAL_PROVIDER_DATA, output);
@@ -474,6 +479,7 @@ public class TvDataBaseManager {
map.put(ChannelInfo.KEY_AUDIO_EXTS, Arrays.toString(channel.getAudioExts()));
map.put(ChannelInfo.KEY_AUDIO_LANGS, DroidLogicTvUtils.TvString.toString(channel.getAudioLangs()));
map.put(ChannelInfo.KEY_AUDIO_TRACK_INDEX, String.valueOf(channel.getAudioTrackIndex()));
+ map.put(ChannelInfo.KEY_AUDIO_OUTPUT_MODE, String.valueOf(channel.getAudioOutPutMode()));
map.put(ChannelInfo.KEY_AUDIO_CHANNEL, String.valueOf(channel.getAudioChannel()));
map.put(ChannelInfo.KEY_SUBT_TYPES, Arrays.toString(channel.getSubtitleTypes()));
map.put(ChannelInfo.KEY_SUBT_PIDS, Arrays.toString(channel.getSubtitlePids()));
@@ -482,6 +488,8 @@ public class TvDataBaseManager {
map.put(ChannelInfo.KEY_SUBT_ID2S, Arrays.toString(channel.getSubtitleId2s()));
map.put(ChannelInfo.KEY_SUBT_LANGS, DroidLogicTvUtils.TvString.toString(channel.getSubtitleLangs()));
map.put(ChannelInfo.KEY_SUBT_TRACK_INDEX, String.valueOf(channel.getSubtitleTrackIndex()));
+ map.put(ChannelInfo.KEY_CONTENT_RATINGS, DroidLogicTvUtils.TvString.toString(channel.getContentRatings()));
+ map.put(ChannelInfo.KEY_SIGNAL_TYPE, DroidLogicTvUtils.TvString.toString(channel.getSignalType()));
return map;
}
@@ -746,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);
@@ -1123,7 +1250,7 @@ public class TvDataBaseManager {
private static final int BATCH_OPERATION_COUNT = 100;
- private boolean isATSCSpecialProgram(Program program) {
+ private static boolean isATSCSpecialProgram(Program program) {
//If program's startTime == EndTime == 0,
//it is a special program for descr update in atsc.
return program.getStartTimeUtcMillis() == 0
@@ -1141,16 +1268,115 @@ public class TvDataBaseManager {
* information.
*/
public void updatePrograms(Uri channelUri, List<Program> newPrograms) {
- updatePrograms(channelUri, newPrograms, false);
+ updatePrograms(channelUri, newPrograms, null, false);
+ }
+
+ public static final class ComparatorValues implements Comparator<Program> {
+ @Override
+ public int compare(Program object1, Program object2) {
+ long m1 = object1.getStartTimeUtcMillis();
+ long m2 = object2.getStartTimeUtcMillis();
+ int result = 0;
+ if (m1 > m2)
+ {
+ result = 1;
+ }
+ if (m1 < m2)
+ {
+ result=-1;
+ }
+ return result;
+ }
}
- public void updatePrograms(Uri channelUri, List<Program> newPrograms, boolean isAtsc) {
+ public boolean isProgramAtTime(Program program, Long timeUtcMillis) {
+ return (timeUtcMillis != null
+ && timeUtcMillis >= program.getStartTimeUtcMillis()
+ && timeUtcMillis < program.getEndTimeUtcMillis());
+ }
+
+ public boolean updatePrograms(Long channelId, List<Program> newPrograms, Long timeUtcMillis) {
+ boolean updated = false;
+ Log.d(TAG, "updatePrograms epg start-----");
+ for (Program p: newPrograms) {
+ String sql_start ;
+ Program oldProgram = null;
+ String sql_query ;
+ Cursor cursor ;
+ Log.d(TAG, "updatePrograms epg title:"+p.getTitle()+" des:"+p.getDescription()+" chid:"+p.getChannelId()+" id:"+p.getId()+" start:" + p.getStartTimeUtcMillis() + " end:" + p.getEndTimeUtcMillis());
+ if (isATSCSpecialProgram(p))
+ {
+ // if (true)
+ // continue;
+ //sql_query = "(_id=" + p.getId() + ")";
+ sql_query = "(" + TvContract.Programs.COLUMN_CHANNEL_ID + "=" + channelId + ") AND ("+ TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG2 +"=" + p.getProgramId() + ")";
+ cursor = mContentResolver.query(TvContract.Programs.CONTENT_URI, null, sql_query, null, null);
+ if (cursor != null && cursor.getCount() != 0) {
+ cursor.moveToNext();
+ oldProgram = Program.fromCursor(cursor);
+ }
+ if (cursor != null) {
+ cursor.close();
+ }
+ if (oldProgram != null && !TextUtils.equals(p.getDescription(), oldProgram.getDescription()))
+ {
+ ContentValues vals = new ContentValues();
+ vals.put(TvContract.Programs.COLUMN_SHORT_DESCRIPTION, p.getDescription());
+ Log.d(TAG, "updatePrograms sql sql_query:" + sql_query);
+ mContentResolver.update(TvContract.Programs.CONTENT_URI, vals, sql_query, null);
+ }
+ else
+ {
+ Log.d(TAG, "updatePrograms isATSCSpecialProgram true");
+ }
+ }
+ else
+ {
+ sql_start = TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS + "=" + p.getStartTimeUtcMillis() + " AND " + TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS + " = " +p.getEndTimeUtcMillis();
+ oldProgram = null;
+ sql_query = "(" + TvContract.Programs.COLUMN_CHANNEL_ID + "=" + channelId + ") AND (" + sql_start + ")";
+ cursor = mContentResolver.query(TvContract.Programs.CONTENT_URI, null, sql_query, null, null);
+ if (cursor != null && cursor.getCount() != 0) {
+ cursor.moveToNext();
+ oldProgram = Program.fromCursor(cursor);
+ }
+ if (cursor != null) {
+ cursor.close();
+ }
+ if (oldProgram == null || !isProgramEq(oldProgram, p))
+ {
+ sql_start = TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS + "<=" + p.getStartTimeUtcMillis() + " AND " + TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS + " > " +p.getStartTimeUtcMillis();
+ String sql_end = TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS + "<=" + p.getEndTimeUtcMillis() + " AND " + TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS + " > " +p.getEndTimeUtcMillis();
+ String sql_del = "(" + TvContract.Programs.COLUMN_CHANNEL_ID + "=" + channelId + ") AND ((" + sql_start + ") OR (" + sql_end + "))";
+ if (oldProgram == null) {
+ Log.d(TAG, "updatePrograms oldProgram is null insert sql:" + sql_del);
+ } else {
+ Log.d(TAG, "updatePrograms not eq insert sql:" + sql_del);
+ }
+ mContentResolver.delete(TvContract.Programs.CONTENT_URI, sql_del, null);
+ mContentResolver.insert(TvContract.Programs.CONTENT_URI, p.toContentValues());
+ updated = isProgramAtTime(p, timeUtcMillis);
+ }
+ else
+ {
+ Log.d(TAG, "updatePrograms no insert true");
+ }
+ }
+ }
+ Log.d(TAG, "updatePrograms epg end-----");
+ return updated;
+ }
+ public boolean updatePrograms(Uri channelUri, List<Program> newPrograms, Long timeUtcMillis, boolean isAtsc) {
+ boolean updated = false;
final int fetchedProgramsCount = newPrograms.size();
if (fetchedProgramsCount == 0) {
- return;
+ return updated;
}
List<Program> oldPrograms = getPrograms(TvContract.buildProgramsUriForChannel(channelUri));
+ Collections.sort(newPrograms, new ComparatorValues());
+ Collections.sort(oldPrograms, new ComparatorValues());
+ //Log.d(TAG, "updatePrograms sort programs ");
Program firstNewProgram = null;
for (Program program : newPrograms) {
if (isAtsc && !isATSCSpecialProgram(program)) {
@@ -1159,6 +1385,10 @@ public class TvDataBaseManager {
}
}
+// for (Program p : newPrograms) {
+// Log.d(TAG, "epg todo:cid("+p.getChannelId()+")eid("+p.getProgramId()+")desc("+p.getTitle()+")desc2("+p.getDescription()+")time("+p.getStartTimeUtcMillis()+"-"+p.getEndTimeUtcMillis()+")");
+// }
+
int oldProgramsIndex = 0;
int newProgramsIndex = 0;
@@ -1186,7 +1416,7 @@ public class TvDataBaseManager {
//Log.d(TAG, "ext desr:"+newProgram.getProgramId());
for (Program program : oldPrograms) {
//Log.d(TAG, "old:"+program.getProgramId());
- if (program.getProgramId() == newProgram.getProgramId()) {
+ if (program.getProgramId() == newProgram.getProgramId()) {//same event id
if (TextUtils.equals(program.getDescription(), newProgram.getDescription()))
break;
program.setDescription(newProgram.getDescription());
@@ -1194,7 +1424,15 @@ public class TvDataBaseManager {
TvContract.buildProgramUri(program.getId()))
.withValues(program.toContentValues())
.build());
- Log.d(TAG, "\tupdate descr");
+ /*Program p = new Program.Builder(program)
+ .build();
+ ops.add(ContentProviderOperation.newInsert(TvContract.Programs.CONTENT_URI)
+ .withValues(p.toContentValues())
+ .build());
+ ops.add(ContentProviderOperation.newDelete(TvContract.buildProgramUri(program.getId()))
+ .build());
+ */
+ //Log.d(TAG, "\tepg etm:cid("+program.getChannelId()+")eid("+program.getProgramId()+")");
break;
}
}
@@ -1204,40 +1442,52 @@ public class TvDataBaseManager {
// Exact match. No need to update. Move on to the next programs.
oldProgramsIndex++;
newProgramsIndex++;
- Log.d(TAG, "\tmatch");
+ //Log.d(TAG, "\tepg match:cid("+newProgram.getChannelId()+")eid("+newProgram.getProgramId()+")desc("+newProgram.getTitle()+")time("+newProgram.getStartTimeUtcMillis()+"-"+newProgram.getEndTimeUtcMillis()+")");
} else if (needsUpdate(oldProgram, newProgram)) {
// Partial match. Update the old program with the new one.
// NOTE: Use 'update' in this case instead of 'insert' and 'delete'. There could
// be application specific settings which belong to the old program.
ops.add(ContentProviderOperation.newUpdate(
- TvContract.buildProgramUri(oldProgram.getProgramId()))
+ TvContract.buildProgramUri(oldProgram.getId()))
.withValues(newProgram.toContentValues())
.build());
oldProgramsIndex++;
newProgramsIndex++;
- Log.d(TAG, "\tupdate");
+
+ updated = isProgramAtTime(newProgram, timeUtcMillis);
+
+ Log.d(TAG, "\tepg update:cid("+newProgram.getChannelId()+")eid("+newProgram.getProgramId()+")desc("+newProgram.getTitle()+")time("+newProgram.getStartTimeUtcMillis()+"-"+newProgram.getEndTimeUtcMillis()+")id("+oldProgram.getId()+")");
} else if (oldProgram.getEndTimeUtcMillis() < newProgram.getEndTimeUtcMillis()) {
// No match. Remove the old program first to see if the next program in
// {@code oldPrograms} partially matches the new program.
ops.add(ContentProviderOperation.newDelete(
- TvContract.buildProgramUri(oldProgram.getProgramId()))
+ TvContract.buildProgramUri(oldProgram.getId()))
.build());
oldProgramsIndex++;
- Log.d(TAG, "\tdelete old");
+
+ updated = isProgramAtTime(oldProgram, timeUtcMillis);
+
+ Log.d(TAG, "\tepg delete:"+oldProgram.getId()+":cid("+oldProgram.getChannelId()+")eid("+oldProgram.getProgramId()+")desc("+oldProgram.getTitle()+")time("+oldProgram.getStartTimeUtcMillis()+"-"+oldProgram.getEndTimeUtcMillis()+")");
} else {
if (!isATSCSpecialProgram(newProgram)) {
// No match. The new program does not match any of the old programs. Insert it
// as a new program.
addNewProgram = true;
newProgramsIndex++;
- Log.d(TAG, "\tnew insert");
+
+ updated = isProgramAtTime(newProgram, timeUtcMillis);
+
+ Log.d(TAG, "\tepg new:cid("+newProgram.getChannelId()+")eid("+newProgram.getProgramId()+")desc("+newProgram.getTitle()+")time("+newProgram.getStartTimeUtcMillis()+"-"+newProgram.getEndTimeUtcMillis()+")id("+newProgram.getId()+")");
}
}
} else {
if (!isATSCSpecialProgram(newProgram)) {
// No old programs. Just insert new programs.
addNewProgram = true;
- Log.d(TAG, "no old, insert new");
+
+ updated = isProgramAtTime(newProgram, timeUtcMillis);
+
+ Log.d(TAG, "\tepg new:(old none):cid("+newProgram.getChannelId()+")eid("+newProgram.getProgramId()+")desc("+newProgram.getTitle()+")time("+newProgram.getStartTimeUtcMillis()+"-"+newProgram.getEndTimeUtcMillis()+")id("+newProgram.getId()+")");
}
newProgramsIndex++;
}
@@ -1256,11 +1506,12 @@ public class TvDataBaseManager {
mContentResolver.applyBatch(TvContract.AUTHORITY, ops);
} catch (RemoteException | OperationApplicationException e) {
Log.e(TAG, "Failed to insert programs.", e);
- return;
+ return updated;
}
ops.clear();
}
}
+ return updated;
}
public void updateProgram(Program program) {
@@ -1271,6 +1522,32 @@ public class TvDataBaseManager {
* Returns {@code true} if the {@code oldProgram} program needs to be updated with the
* {@code newProgram} program.
*/
+ private static boolean isProgramEq(Program oldProgram, Program newProgram) {
+ // NOTE: Here, we update the old program if it has the same title and overlaps with the new
+ // program. The test logic is just an example and you can modify this. E.g. check whether
+ // the both programs have the same program ID if your EPG supports any ID for the programs.
+ if (oldProgram.getTitle() == null || oldProgram.getTitle().isEmpty()) {
+ Log.d(TAG, "getTitle is null");
+ return false;
+ } else if (!oldProgram.getTitle().equals(newProgram.getTitle())) {
+ Log.d(TAG, "getTitle is not eq");
+ return false;
+ } else if (oldProgram.getDescription() == null && newProgram.getDescription() != null) {
+ Log.d(TAG, "getDescription is old is null new not null");
+ return false;
+ } else if (!Objects.equals(Program.contentRatingsToString(oldProgram.getContentRatings()),
+ Program.contentRatingsToString(newProgram.getContentRatings()))) {
+ Log.d(TAG, "ratings not eq");
+ return false;
+ } else {
+ Log.d(TAG, "isProgramEq is eq true");
+ return true;
+ }
+ }
+ /**
+ * Returns {@code true} if the {@code oldProgram} program needs to be updated with the
+ * {@code newProgram} program.
+ */
private static boolean needsUpdate(Program oldProgram, Program newProgram) {
// NOTE: Here, we update the old program if it has the same title and overlaps with the new
// program. The test logic is just an example and you can modify this. E.g. check whether
@@ -1373,4 +1650,44 @@ public class TvDataBaseManager {
return program;
}
+
+ public int deleteProgram(ChannelInfo channel) {
+ return deleteProgram(channel.getId());
+ }
+
+ public int deleteProgram(Long channelId) {
+ int deleteCount = mContentResolver.delete(
+ TvContract.Programs.CONTENT_URI,
+ TvContract.Programs.COLUMN_CHANNEL_ID + "=?",
+ new String[] { String.valueOf(channelId)});
+ if (deleteCount > 0) {
+ Log.d(TAG, "Deleted " + deleteCount + " programs");
+ }
+ return deleteCount;
+ }
+
+ public int deleteProgram(Long channelId, String versionNotEqual, String eitExt) {
+ int deleteCount = mContentResolver.delete(
+ TvContract.Programs.CONTENT_URI,
+ TvContract.Programs.COLUMN_CHANNEL_ID + "=? AND "
+ + TvContract.Programs.COLUMN_VERSION_NUMBER + "!=? AND "
+ + TvContract.Programs.COLUMN_INTERNAL_PROVIDER_FLAG3 + "=?",
+ new String[] { String.valueOf(channelId), versionNotEqual, eitExt});
+ if (deleteCount > 0) {
+ Log.d(TAG, "Deleted " + deleteCount + " programs");
+ }
+ return deleteCount;
+ }
+
+ public int deletePrograms(Long channelId, String versionNotEqual) {
+ int deleteCount = mContentResolver.delete(
+ TvContract.Programs.CONTENT_URI,
+ TvContract.Programs.COLUMN_CHANNEL_ID + "=? AND "
+ + TvContract.Programs.COLUMN_VERSION_NUMBER + "!=?",
+ new String[] { String.valueOf(channelId), versionNotEqual});
+ if (deleteCount > 0) {
+ Log.d(TAG, "Deleted " + deleteCount + " programs");
+ }
+ return deleteCount;
+ }
}
diff --git a/core/java/com/droidlogic/app/tv/TvInputBaseSession.java b/core/java/com/droidlogic/app/tv/TvInputBaseSession.java
index 0993620..f28af29 100644
--- a/core/java/com/droidlogic/app/tv/TvInputBaseSession.java
+++ b/core/java/com/droidlogic/app/tv/TvInputBaseSession.java
@@ -46,6 +46,9 @@ public abstract class TvInputBaseSession extends TvInputService.Session implemen
private TvControlManager mTvControlManager;
protected DroidLogicOverlayView mOverlayView = null;
+ protected boolean isBlockNoRatingEnable = false;
+ protected boolean isUnlockCurrent_NR = false;
+
public TvInputBaseSession(Context context, String inputId, int deviceId) {
super(context);
mContext = context;
@@ -54,6 +57,10 @@ public abstract class TvInputBaseSession extends TvInputService.Session implemen
mTvControlManager = TvControlManager.getInstance();
mSessionHandler = new Handler(context.getMainLooper(), this);
+ int block_norating = Settings.System.getInt(mContext.getContentResolver(), DroidLogicTvUtils.BLOCK_NORATING, 0);
+ isBlockNoRatingEnable = block_norating == 0 ? false : true;
+ if (DEBUG)
+ Log.d(TAG, "isBlockNoRatingEnable = " + isBlockNoRatingEnable);
}
public void setSessionId(int id) {
@@ -74,7 +81,7 @@ public abstract class TvInputBaseSession extends TvInputService.Session implemen
public void doRelease() {
Log.d(TAG, "doRelease");
- setAudiodMute(false);
+ //setAudiodMute(false);
setOverlayViewEnabled(false);
if (mOverlayView != null) {
mOverlayView.releaseResource();
@@ -158,12 +165,10 @@ public abstract class TvInputBaseSession extends TvInputService.Session implemen
@Override
public void notifyVideoUnavailable(int reason) {
Log.d(TAG, "notifyVideoUnavailable: "+reason);
+ super.notifyVideoUnavailable(reason);
if (mOverlayView != null) {
- super.notifyVideoAvailable();
mOverlayView.setImageVisibility(true);
mOverlayView.setTextVisibility(false);
- } else {
- super.notifyVideoUnavailable(reason);
}
}
@@ -171,18 +176,17 @@ public abstract class TvInputBaseSession extends TvInputService.Session implemen
if (mOverlayView != null) {
mOverlayView.setImageVisibility(false);
mOverlayView.setTextVisibility(false);
+ mOverlayView.setSubtitleVisibility(false);
}
}
private void setAudiodMute(boolean mute) {
if (mute) {
- SystemProperties.set("persist.sys.tvview.blocked", "true");
- mTvControlManager.SetAudioMuteForTv(TvControlManager.AUDIO_MUTE_FOR_TV);
- mTvControlManager.SetAudioMuteKeyStatus(TvControlManager.AUDIO_MUTE_FOR_TV);
+ //SystemProperties.set("persist.sys.tvview.blocked", "true");
+ mTvControlManager.setAmAudioPreMute(TvControlManager.AUDIO_MUTE_FOR_TV);
} else {
- SystemProperties.set("persist.sys.tvview.blocked", "false");
- mTvControlManager.SetAudioMuteForTv(TvControlManager.AUDIO_UNMUTE_FOR_TV);
- mTvControlManager.SetAudioMuteKeyStatus(TvControlManager.AUDIO_UNMUTE_FOR_TV);
+ //SystemProperties.set("persist.sys.tvview.blocked", "false");
+ mTvControlManager.setAmAudioPreMute(TvControlManager.AUDIO_UNMUTE_FOR_TV);
}
}
diff --git a/core/java/com/droidlogic/app/tv/TvStoreManager.java b/core/java/com/droidlogic/app/tv/TvStoreManager.java
index 7f4c315..155923d 100644
--- a/core/java/com/droidlogic/app/tv/TvStoreManager.java
+++ b/core/java/com/droidlogic/app/tv/TvStoreManager.java
@@ -9,8 +9,15 @@ import android.util.Log;
import android.os.Bundle;
import android.content.Context;
import android.media.tv.TvContract;
-import android.provider.Settings;
-
+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;
+import com.droidlogic.app.tv.TvControlManager.TvMode;
public abstract class TvStoreManager {
public static final String TAG = "TvStoreManager";
@@ -26,16 +33,24 @@ public abstract class TvStoreManager {
private TvControlManager.ScanMode mScanMode = null;
private TvControlManager.SortMode mSortMode = null;
-
+ private TvControlManager mTvControlManager = null;
private ArrayList<TvControlManager.ScannerLcnInfo> mLcnInfo = null;
/*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;
+ private ArrayList<FreqList> mATSC_C_LRC = null;
+ private ArrayList<FreqList> mATSC_HRC = null;
private boolean on_channel_store_tschanged = true;
@@ -51,9 +66,12 @@ public abstract class TvStoreManager {
mInitialLcnNumber = mInitialDisplayNumber;
mTvDataBaseManager = new TvDataBaseManager(mContext);
-
+ 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) {
@@ -69,8 +87,9 @@ public abstract class TvStoreManager {
public abstract void onScanEnd();
- public void onScanExit() {}
+ public void onScanExit(int freg) {}
+ public void onScanEndBeforeStore(int freg) {}
private Bundle getScanEventBundle(TvControlManager.ScannerEvent mEvent) {
Bundle bundle = new Bundle();
@@ -162,8 +181,20 @@ 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) {
+ mChannelsExist = mTvDataBaseManager.getChannelList(mInputId, TvContract.Channels.SERVICE_TYPE_AUDIO_VIDEO);
+ 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;
String serviceType;
@@ -237,6 +268,9 @@ public abstract class TvStoreManager {
.setAccessControled(event.accessControlled)
.setHidden(event.hidden)
.setHideGuide(event.hideGuide)
+ .setVct(event.vct)
+ .setSignalType(DroidLogicTvUtils.getCurrentSignalType(mContext) == DroidLogicTvUtils.SIGNAL_TYPE_ERROR
+ ? TvContract.Channels.TYPE_ATSC_T : DroidLogicTvUtils.getCurrentSignalType(mContext))
.build();
}
@@ -313,6 +347,9 @@ public abstract class TvStoreManager {
.setAccessControled(event.accessControlled)
.setHidden(event.hidden)
.setHideGuide(event.hideGuide)
+ .setContentRatings(null)
+ .setSignalType(DroidLogicTvUtils.getCurrentSignalType(mContext) == DroidLogicTvUtils.SIGNAL_TYPE_ERROR
+ ? TvContract.Channels.TYPE_ATSC_T : DroidLogicTvUtils.getCurrentSignalType(mContext))
.build();
}
@@ -339,9 +376,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) {
@@ -351,6 +393,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)
@@ -569,6 +658,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);
@@ -610,10 +705,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());
@@ -621,8 +719,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());
@@ -630,19 +728,152 @@ 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;
on_channel_store_tschanged = true;
mChannelsOld = null;
mChannelsNew = null;
+ 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++) {
+ if (chan.getDisplayNumber().equals(mChannelsExist.get(i).getDisplayNumber()) && (chan.getFrequency() != mChannelsExist.get(i).getFrequency())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private int getDvbPhysicalNumFromListByFre(ArrayList<FreqList> mlist, int freq, int diff) {
+ int size = mlist.size();
+ for (int i = 0; i < size; i++) {
+ if (freq == mlist.get(i).freq) {
+ return i + 2;
+ }
+ }
+ for (int i = 0; i < size; i++) {
+ if (mlist.get(i).freq - diff < freq && freq < mlist.get(i).freq + diff) {
+ return i + 2;
+ }
+ }
+ return -1;
+ }
+
+ private int getDvbPhysicalNumByFre(TvMode tvMode, int freq) {
+
+ int diff = 3000000;
+ String type = tvMode.toType();
+ int physicalNum = -1;
+ Log.d(TAG, "type:" + type + " freq :" + freq);
+ if (type.equals(TvContract.Channels.TYPE_ATSC_T)) {
+ tvMode.setList(0);
+ if (mATSC_T == null) {
+ mATSC_T = mTvControlManager.DTVGetScanFreqList(tvMode.getMode());
+ }
+ physicalNum = getDvbPhysicalNumFromListByFre(mATSC_T, freq, diff);
+ return physicalNum;
+ }
+ if (type.equals(TvContract.Channels.TYPE_ATSC_C)) {
+ tvMode.setList(1);
+ if (mATSC_C_STD == null) {
+ mATSC_C_STD = mTvControlManager.DTVGetScanFreqList(tvMode.getMode());
+ }
+ physicalNum = getDvbPhysicalNumFromListByFre(mATSC_C_STD, freq, diff);
+ if (physicalNum != -1) {
+ //error
+ return physicalNum;
+ }
+ tvMode.setList(2);
+ if (mATSC_C_LRC == null) {
+ mATSC_C_LRC = mTvControlManager.DTVGetScanFreqList(tvMode.getMode());
+ }
+ physicalNum = getDvbPhysicalNumFromListByFre(mATSC_C_LRC, freq, diff);
+ if (physicalNum != -1) {
+ //error
+ return physicalNum;
+ }
+ tvMode.setList(3);
+ if (mATSC_HRC == null) {
+ mATSC_HRC = mTvControlManager.DTVGetScanFreqList(tvMode.getMode());
+ }
+ physicalNum = getDvbPhysicalNumFromListByFre(mATSC_HRC, freq, diff);
+ if (physicalNum != -1) {
+ //error
+ return physicalNum;
+ }
+ }
+ 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;
-
+ TvMode mode = null;
+ int freq = 0;
+ int physicalNum = -1;
Log.d(TAG, "onEvent:" + event.type + " :" + mDisplayNumber);
switch (event.type) {
@@ -677,8 +908,11 @@ public abstract class TvStoreManager {
}
if (mScanMode.isDTVManulScan())
- initChannelsExist();
-
+ initChannelsExist();
+ /*get exist channel info list*/
+ reinitChannels();
+ TvControlManager.FEParas fep =
+ new TvControlManager.FEParas(DroidLogicTvUtils.getObjectString(event.paras, "fe"));
channel = createDtvChannelInfo(event);
if (mDisplayNumber2 != null)
@@ -690,13 +924,38 @@ public abstract class TvStoreManager {
channel.setDisplayNumber(""+event.majorChannelNumber+"-"+event.minorChannelNumber);
int vct = DroidLogicTvUtils.getObjectValueInt(event.paras, "srv", "vct", 0);
Log.d(TAG, "srv.vct:"+vct);
- if (vct == 1)//one-part channnel numbers for digital cable system.
- channel.setDisplayNumber(""+event.minorChannelNumber);
+ if (vct == 1 && ((event.majorChannelNumber >> 4) == 0x3f)) {
+ //one-part channnel numbers for digital cable system.
+ //see atsc a/65 page 35, if major_channel_number hi 6 bit is 11 1111
+ //one_part_number = (major_channel_number & 0x00f) << 10 + mino_channel_number
+ int one_part_number = ((event.majorChannelNumber & 0x00f) << 10) + event.minorChannelNumber;
+ Log.d(TAG, "set one_part_number:"+ one_part_number + " maj:" + event.majorChannelNumber + " min:" +event.minorChannelNumber);
+ if (one_part_number == 0) {
+ mode = fep.getMode();
+ freq = fep.getFrequency();
+ physicalNum = getDvbPhysicalNumByFre(mode, freq);
+ if (physicalNum > 0)
+ channel.setDisplayNumber(""+physicalNum+"-"+channel.getServiceId());
+ else
+ channel.setDisplayNumber("0"+"-"+channel.getServiceId());
+ } else {
+ channel.setDisplayNumber(""+one_part_number);
+ }
+ }
}
- Log.d(TAG, "reset number to " + channel.getDisplayNumber());
-
+ /*if (getIsSameDisplayNumber(channel) == true) {
+ //is same
+ mode = fep.getMode();
+ freq = fep.getFrequency();
+ physicalNum = getDvbPhysicalNumByFre(mode, freq);
+ if (physicalNum > 0)
+ channel.setDisplayNumber(""+physicalNum+"-"+channel.getServiceId());
+ Log.d(TAG, "----Channels physicalNum set DisplayName:" + physicalNum + " getDisplayNumber:" + channel.getDisplayNumber());
+ }*/
channel.print();
+ /*add seach channel*/
+ mChannelsExist.add(channel);
cacheChannel(event, channel);
if (mDisplayNumber2 != null) {
@@ -712,7 +971,6 @@ public abstract class TvStoreManager {
case TvControlManager.EVENT_ATV_PROG_DATA:
Log.d(TAG, "atv prog data");
-
checkOrPatchBeginLost(event);
if (isFinalStoreStage && !mScanMode.isATVManualScan())
@@ -750,7 +1008,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);
@@ -786,7 +1044,10 @@ public abstract class TvStoreManager {
case TvControlManager.EVENT_STORE_END:
Log.d(TAG, "Store end");
-
+ if (null != mChannelsNew && 0 != mChannelsNew.size()) {
+ Log.d(TAG, "Store end mChannelsNew.size=" + mChannelsNew.size());
+ onScanEndBeforeStore(event.freq);
+ }
storeTvChannel(isRealtimeStore, isFinalStoreStage);
bundle = getScanEventBundle(event);
@@ -815,8 +1076,9 @@ public abstract class TvStoreManager {
}
mScanMode = null;
+ mChannelsAll = null;
- onScanExit();
+ onScanExit(event.freq);
bundle = getScanEventBundle(event);
onEvent(DroidLogicTvUtils.SIG_INFO_C_SCAN_EXIT_EVENT, bundle);
@@ -827,5 +1089,12 @@ public abstract class TvStoreManager {
}
}
+ private class ChildCallback implements Handler.Callback {
+ @Override
+ public boolean handleMessage(Message msg) {
+ dealStoreEvent((TvControlManager.ScannerEvent)msg.obj);
+ return false;
+ }
+ }
}
diff --git a/libtvbinder/include/tvcmd.h b/libtvbinder/include/tvcmd.h
index 7f1b3fd..eec85e2 100644
--- a/libtvbinder/include/tvcmd.h
+++ b/libtvbinder/include/tvcmd.h
@@ -257,6 +257,11 @@ enum tvcmd_e {
EPG_EVENT_CALLBACK = 542,
VFRAME_BMP_EVENT_CALLBACK = 543,
SCANNING_FRAME_STABLE_CALLBACK = 544,
+ FRONTEND_EVENT_CALLBACK = 545,
+ RECORDER_EVENT_CALLBACK = 546,
+ SCAN_LCN_CALLBACK = 547,
+ RRT_EVENT_CALLBACK = 548,
+ EAS_EVENT_CALLBACK = 549,
// CALLBACK END
// SSM
@@ -481,9 +486,6 @@ enum tvcmd_e {
DTV_GET_AUDIO_CHANNEL_MOD = 1427,
DTV_GET_FREQ_BY_PROG_ID = 1428,
DTV_GET_VIDEO_FMT_INFO = 1429,
- DTV_START_RECORD = 1430,
- DTV_STOP_RECORD = 1431,
- //DTV_SET_RECORD_ALL_TS = 1432,
SAVE_PROGRAM_ID = 1440,
GET_PROGRAM_ID = 1441,
DTV_SET_AUDIO_AD = 1442,
@@ -509,6 +511,18 @@ enum tvcmd_e {
SET_AUDIO_OUTMODE = 1501,
GET_AUDIO_OUTMODE = 1502,
+ GET_AUDIO_STREAM_OUTMODE = 1503,
+
+ SET_AMAUDIO_VOLUME = 1504,
+ GET_AMAUDIO_VOLUME = 1505,
+ SAVE_AMAUDIO_VOLUME = 1506,
+ GET_SAVE_AMAUDIO_VOLUME = 1507,
+ DTV_UPDATE_RRT = 1508,
+ DTV_SEARCH_RRT = 1509,
+ DTV_UPDATE_EAS = 1510,
+
+ DTV_RECORDING_CMD = 1600,
+ DTV_PLAY_CMD = 1610,
};
#endif //ANDROID_AMLOGIC_TVCMD_H