diff options
author | Youngsang Cho <youngsang@google.com> | 2016-10-31 15:28:42 -0700 |
---|---|---|
committer | Youngsang Cho <youngsang@google.com> | 2016-10-31 15:28:42 -0700 |
commit | 919e1ed7e914029a1a0054237d86dc7b19ced898 (patch) | |
tree | cb30cfbafd80e01d314868cdc36e783d39981119 /src/com/android/tv/tuner/util | |
parent | 2933fcfd17f59c086436b270e7c01f2afcd54aa5 (diff) | |
download | TV-919e1ed7e914029a1a0054237d86dc7b19ced898.tar.gz |
Sync to ub-tv-killing at 6f6e46557accb62c9548e4177d6005aa944dbf33
Change-Id: I873644d6d9d0110c981ef6075cb4019c16bbb94b
Diffstat (limited to 'src/com/android/tv/tuner/util')
-rw-r--r-- | src/com/android/tv/tuner/util/ByteArrayBuffer.java | 149 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/ConvertUtils.java | 35 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/GlobalSettingsUtils.java | 36 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/Ints.java | 28 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/StatusTextUtils.java | 119 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/StringUtils.java | 38 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/SystemPropertiesProxy.java | 61 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/TisConfiguration.java | 22 | ||||
-rw-r--r-- | src/com/android/tv/tuner/util/TunerInputInfoUtils.java | 100 |
9 files changed, 588 insertions, 0 deletions
diff --git a/src/com/android/tv/tuner/util/ByteArrayBuffer.java b/src/com/android/tv/tuner/util/ByteArrayBuffer.java new file mode 100644 index 00000000..da887e7d --- /dev/null +++ b/src/com/android/tv/tuner/util/ByteArrayBuffer.java @@ -0,0 +1,149 @@ +/* + * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/util/ByteArrayBuffer.java $ + * $Revision: 496070 $ + * $Date: 2007-01-14 04:18:34 -0800 (Sun, 14 Jan 2007) $ + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + */ + +package com.android.tv.tuner.util; + +/** + * An expandable byte buffer built on byte array. + */ +public final class ByteArrayBuffer { + + private byte[] buffer; + private int len; + + public ByteArrayBuffer(int capacity) { + super(); + if (capacity < 0) { + throw new IllegalArgumentException("Buffer capacity may not be negative"); + } + this.buffer = new byte[capacity]; + } + + private void expand(int newlen) { + byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)]; + System.arraycopy(this.buffer, 0, newbuffer, 0, this.len); + this.buffer = newbuffer; + } + + public void append(final byte[] b, int off, int len) { + if (b == null) { + return; + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException(); + } + if (len == 0) { + return; + } + int newlen = this.len + len; + if (newlen > this.buffer.length) { + expand(newlen); + } + System.arraycopy(b, off, this.buffer, this.len, len); + this.len = newlen; + } + + public void append(int b) { + int newlen = this.len + 1; + if (newlen > this.buffer.length) { + expand(newlen); + } + this.buffer[this.len] = (byte) b; + this.len = newlen; + } + + public void append(final char[] b, int off, int len) { + if (b == null) { + return; + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException(); + } + if (len == 0) { + return; + } + int oldlen = this.len; + int newlen = oldlen + len; + if (newlen > this.buffer.length) { + expand(newlen); + } + for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) { + this.buffer[i2] = (byte) b[i1]; + } + this.len = newlen; + } + + public void clear() { + this.len = 0; + } + + public byte[] toByteArray() { + byte[] b = new byte[this.len]; + if (this.len > 0) { + System.arraycopy(this.buffer, 0, b, 0, this.len); + } + return b; + } + + public int byteAt(int i) { + return this.buffer[i]; + } + + public int capacity() { + return this.buffer.length; + } + + public int length() { + return this.len; + } + + public byte[] buffer() { + return this.buffer; + } + + public void setLength(int len) { + if (len < 0 || len > this.buffer.length) { + throw new IndexOutOfBoundsException(); + } + this.len = len; + } + + public boolean isEmpty() { + return this.len == 0; + } + + public boolean isFull() { + return this.len == this.buffer.length; + } + +} diff --git a/src/com/android/tv/tuner/util/ConvertUtils.java b/src/com/android/tv/tuner/util/ConvertUtils.java new file mode 100644 index 00000000..abf18d8c --- /dev/null +++ b/src/com/android/tv/tuner/util/ConvertUtils.java @@ -0,0 +1,35 @@ +/* + * 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.android.tv.tuner.util; + +/** + * Utility class for converting date and time. + */ +public class ConvertUtils { + // Time diff between 1.1.1970 00:00:00 and 6.1.1980 00:00:00 + private static final long DIFF_BETWEEN_UNIX_EPOCH_AND_GPS = 315964800; + + private ConvertUtils() { } + + public static long convertGPSTimeToUnixEpoch(long gpsTime) { + return gpsTime + DIFF_BETWEEN_UNIX_EPOCH_AND_GPS; + } + + public static long convertUnixEpochToGPSTime(long epochTime) { + return epochTime - DIFF_BETWEEN_UNIX_EPOCH_AND_GPS; + } +} diff --git a/src/com/android/tv/tuner/util/GlobalSettingsUtils.java b/src/com/android/tv/tuner/util/GlobalSettingsUtils.java new file mode 100644 index 00000000..0cefcbed --- /dev/null +++ b/src/com/android/tv/tuner/util/GlobalSettingsUtils.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 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.android.tv.tuner.util; + +import android.content.Context; +import android.provider.Settings; + +/** + * Utility class that get information of global settings. + */ +public class GlobalSettingsUtils { + // Since global surround setting is hided, add the related variable here for checking surround + // sound setting when the audio is unavailable. Remove this workaround after b/31254857 fixed. + private static final String ENCODED_SURROUND_OUTPUT = "encoded_surround_output"; + public static final int ENCODED_SURROUND_OUTPUT_NEVER = 1; + + private GlobalSettingsUtils () { } + + public static int getEncodedSurroundOutputSettings(Context context) { + return Settings.Global.getInt(context.getContentResolver(), ENCODED_SURROUND_OUTPUT, 0); + } +} diff --git a/src/com/android/tv/tuner/util/Ints.java b/src/com/android/tv/tuner/util/Ints.java new file mode 100644 index 00000000..0b1be426 --- /dev/null +++ b/src/com/android/tv/tuner/util/Ints.java @@ -0,0 +1,28 @@ +package com.android.tv.tuner.util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Static utility methods pertaining to int primitives. (Referred Guava's Ints class) + */ +public class Ints { + private Ints() {} + + public static int[] toArray(List<Integer> integerList) { + int[] intArray = new int[integerList.size()]; + int i = 0; + for (Integer data : integerList) { + intArray[i++] = data; + } + return intArray; + } + + public static List<Integer> asList(int[] intArray) { + List<Integer> integerList = new ArrayList<>(intArray.length); + for (int data : intArray) { + integerList.add(data); + } + return integerList; + } +} diff --git a/src/com/android/tv/tuner/util/StatusTextUtils.java b/src/com/android/tv/tuner/util/StatusTextUtils.java new file mode 100644 index 00000000..2633834b --- /dev/null +++ b/src/com/android/tv/tuner/util/StatusTextUtils.java @@ -0,0 +1,119 @@ +/* + * 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.android.tv.tuner.util; + +import java.util.Locale; + +/** + * Utility class for tuner status messages. + */ +public class StatusTextUtils { + private static final int PACKETS_PER_SEC_YELLOW = 1500; + private static final int PACKETS_PER_SEC_RED = 1000; + private static final int AUDIO_POSITION_MS_RATE_DIFF_YELLOW = 100; + private static final int AUDIO_POSITION_MS_RATE_DIFF_RED = 200; + private static final String COLOR_RED = "red"; + private static final String COLOR_YELLOW = "yellow"; + private static final String COLOR_GREEN = "green"; + private static final String COLOR_GRAY = "gray"; + + private StatusTextUtils() { } + + /** + * Returns tuner status warning message in HTML. + * + * <p>This is only called for debuging and always shown in english.</p> + */ + public static String getStatusWarningInHTML(long packetsPerSec, + int videoFrameDrop, int bytesInQueue, + long audioPositionUs, long audioPositionUsRate, + long audioPtsUs, long audioPtsUsRate, + long videoPtsUs, long videoPtsUsRate) { + StringBuffer buffer = new StringBuffer(); + + // audioPosition should go in rate of 1000ms. + long audioPositionMsRate = audioPositionUsRate / 1000; + String audioPositionColor; + if (Math.abs(audioPositionMsRate - 1000) > AUDIO_POSITION_MS_RATE_DIFF_RED) { + audioPositionColor = COLOR_RED; + } else if (Math.abs(audioPositionMsRate - 1000) > AUDIO_POSITION_MS_RATE_DIFF_YELLOW) { + audioPositionColor = COLOR_YELLOW; + } else { + audioPositionColor = COLOR_GRAY; + } + buffer.append(String.format(Locale.US, "<font color=%s>", audioPositionColor)); + buffer.append( + String.format(Locale.US, "audioPositionMs: %d (%d)<br>", audioPositionUs / 1000, + audioPositionMsRate)); + buffer.append("</font>\n"); + buffer.append("<font color=" + COLOR_GRAY + ">"); + buffer.append(String.format(Locale.US, "audioPtsMs: %d (%d, %d)<br>", audioPtsUs / 1000, + audioPtsUsRate / 1000, (audioPtsUs - audioPositionUs) / 1000)); + buffer.append(String.format(Locale.US, "videoPtsMs: %d (%d, %d)<br>", videoPtsUs / 1000, + videoPtsUsRate / 1000, (videoPtsUs - audioPositionUs) / 1000)); + buffer.append("</font>\n"); + + appendStatusLine(buffer, "KbytesInQueue", bytesInQueue / 1000, 1, 10); + buffer.append("<br/>"); + appendErrorStatusLine(buffer, "videoFrameDrop", videoFrameDrop, 0, 2); + buffer.append("<br/>"); + appendStatusLine(buffer, "packetsPerSec", packetsPerSec, PACKETS_PER_SEC_RED, + PACKETS_PER_SEC_YELLOW); + return buffer.toString(); + } + + /** + * Returns audio unavailable warning message in HTML. + */ + public static String getAudioWarningInHTML(String msg) { + return String.format("<font color=%s>%s</font>\n", COLOR_YELLOW, msg); + } + + private static void appendStatusLine(StringBuffer buffer, String factorName, long value, + int minRed, int minYellow) { + buffer.append("<font color="); + if (value <= minRed) { + buffer.append(COLOR_RED); + } else if (value <= minYellow) { + buffer.append(COLOR_YELLOW); + } else { + buffer.append(COLOR_GREEN); + } + buffer.append(">"); + buffer.append(factorName); + buffer.append(" : "); + buffer.append(value); + buffer.append("</font>"); + } + + private static void appendErrorStatusLine(StringBuffer buffer, String factorName, int value, + int minGreen, int minYellow) { + buffer.append("<font color="); + if (value <= minGreen) { + buffer.append(COLOR_GREEN); + } else if (value <= minYellow) { + buffer.append(COLOR_YELLOW); + } else { + buffer.append(COLOR_RED); + } + buffer.append(">"); + buffer.append(factorName); + buffer.append(" : "); + buffer.append(value); + buffer.append("</font>"); + } +} diff --git a/src/com/android/tv/tuner/util/StringUtils.java b/src/com/android/tv/tuner/util/StringUtils.java new file mode 100644 index 00000000..15571e75 --- /dev/null +++ b/src/com/android/tv/tuner/util/StringUtils.java @@ -0,0 +1,38 @@ +/* + * 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.android.tv.tuner.util; + +/** + * Utility class for handling {@link String}. + */ +public final class StringUtils { + + private StringUtils() { } + + /** + * Returns compares two strings lexicographically and handles null values quietly. + */ + public static int compare(String a, String b) { + if (a == null) { + return b == null ? 0 : -1; + } + if (b == null) { + return 1; + } + return a.compareTo(b); + } +} diff --git a/src/com/android/tv/tuner/util/SystemPropertiesProxy.java b/src/com/android/tv/tuner/util/SystemPropertiesProxy.java new file mode 100644 index 00000000..62a64361 --- /dev/null +++ b/src/com/android/tv/tuner/util/SystemPropertiesProxy.java @@ -0,0 +1,61 @@ +/* + * 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.android.tv.tuner.util; + +import android.util.Log; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Proxy class that gives an access to a hidden API {@link android.os.SystemProperties#getBoolean}. + */ +public class SystemPropertiesProxy { + private static final String TAG = "SystemPropertiesProxy"; + + private SystemPropertiesProxy() { } + + public static boolean getBoolean(String key, boolean def) + throws IllegalArgumentException { + try { + Class SystemPropertiesClass = Class.forName("android.os.SystemProperties"); + Method getBooleanMethod = SystemPropertiesClass.getDeclaredMethod("getBoolean", + String.class, boolean.class); + getBooleanMethod.setAccessible(true); + return (boolean) getBooleanMethod.invoke(SystemPropertiesClass, key, def); + } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException + | ClassNotFoundException e) { + Log.e(TAG, "Failed to invoke SystemProperties.getBoolean()", e); + } + return def; + } + + public static int getInt(String key, int def) + throws IllegalArgumentException { + try { + Class SystemPropertiesClass = Class.forName("android.os.SystemProperties"); + Method getIntMethod = SystemPropertiesClass.getDeclaredMethod("getInt", + String.class, int.class); + getIntMethod.setAccessible(true); + return (int) getIntMethod.invoke(SystemPropertiesClass, key, def); + } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException + | ClassNotFoundException e) { + Log.e(TAG, "Failed to invoke SystemProperties.getInt()", e); + } + return def; + } +} diff --git a/src/com/android/tv/tuner/util/TisConfiguration.java b/src/com/android/tv/tuner/util/TisConfiguration.java new file mode 100644 index 00000000..ca861d67 --- /dev/null +++ b/src/com/android/tv/tuner/util/TisConfiguration.java @@ -0,0 +1,22 @@ +package com.android.tv.tuner.util; + +import android.content.Context; + +/** + * A helper class of tuner configuration. + */ +public class TisConfiguration { + private static final String LC_PACKAGE_NAME = "com.android.tv"; + + public static boolean isPackagedWithLiveChannels(Context context) { + return (LC_PACKAGE_NAME.equals(context.getPackageName())); + } + + public static boolean isInternalTunerTvInput(Context context) { + return (!LC_PACKAGE_NAME.equals(context.getPackageName())); + } + + public static int getTunerHwDeviceId(Context context) { + return 0; // FIXME: Make it OEM configurable + } +} diff --git a/src/com/android/tv/tuner/util/TunerInputInfoUtils.java b/src/com/android/tv/tuner/util/TunerInputInfoUtils.java new file mode 100644 index 00000000..5c411f64 --- /dev/null +++ b/src/com/android/tv/tuner/util/TunerInputInfoUtils.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2016 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.android.tv.tuner.util; + +import android.annotation.TargetApi; +import android.content.ComponentName; +import android.content.Context; +import android.media.tv.TvInputInfo; +import android.media.tv.TvInputManager; +import android.os.Build; +import android.support.annotation.Nullable; +import android.support.v4.os.BuildCompat; +import android.util.Log; + +import com.android.tv.common.feature.CommonFeatures; +import com.android.tv.tuner.R; +import com.android.tv.tuner.TunerHal; +import com.android.tv.tuner.tvinput.TunerTvInputService; + +/** + * Utility class for providing tuner input info. + */ +public class TunerInputInfoUtils { + private static final String TAG = "TunerInputInfoUtils"; + private static final boolean DEBUG = false; + + /** + * Builds tuner input's info. + */ + @Nullable + @TargetApi(Build.VERSION_CODES.N) + public static TvInputInfo buildTunerInputInfo(Context context, boolean fromBuiltInTuner) { + int numOfDevices = TunerHal.getTunerCount(context); + if (numOfDevices == 0) { + return null; + } + TvInputInfo.Builder builder = new TvInputInfo.Builder(context, new ComponentName(context, + TunerTvInputService.class)); + if (fromBuiltInTuner) { + builder.setLabel(R.string.bt_app_name); + } else { + builder.setLabel(R.string.ut_app_name); + } + try { + return builder.setCanRecord(CommonFeatures.DVR.isEnabled(context)) + .setTunerCount(numOfDevices) + .build(); + } catch (NullPointerException e) { + // TunerTvInputService is not enabled. + return null; + } + } + + /** + * Updates tuner input's info. + * + * @param context {@link Context} instance + */ + public static void updateTunerInputInfo(Context context) { + if (BuildCompat.isAtLeastN()) { + if (DEBUG) Log.d(TAG, "updateTunerInputInfo()"); + TvInputInfo info = buildTunerInputInfo(context, isBuiltInTuner(context)); + if (info != null) { + ((TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE)) + .updateTvInputInfo(info); + if (DEBUG) { + Log.d(TAG, "TvInputInfo [" + info.loadLabel(context) + + "] updated: " + info.toString()); + } + } else { + if (DEBUG) { + Log.d(TAG, "Updating tuner input's info failed. Input is not ready yet."); + } + } + } + } + + /** + * Returns if the current tuner service is for a built-in tuner. + * + * @param context {@link Context} instance + */ + public static boolean isBuiltInTuner(Context context) { + return TunerHal.getTunerType(context) == TunerHal.TUNER_TYPE_BUILT_IN; + } +} |