Snap for 9550355 from 2823b1be937d343f9775c10c9ce1f95b58861ea8 to sdk-release

Change-Id: I320dd5bb7b5f36933a10e8bb50352a94bf1e10a0
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2cff92d..75e2c4d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -42,6 +42,7 @@
     <uses-permission android:name="com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS"/>
     <!-- Permissions/feature for USB tuner -->
     <uses-permission android:name="android.permission.DVB_DEVICE"/>
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
 
     <uses-feature android:name="android.hardware.usb.host"
          android:required="false"/>
diff --git a/common/src/com/android/tv/common/CommonPreferences.java b/common/src/com/android/tv/common/CommonPreferences.java
index 5a94eec..72acfd1 100644
--- a/common/src/com/android/tv/common/CommonPreferences.java
+++ b/common/src/com/android/tv/common/CommonPreferences.java
@@ -164,7 +164,8 @@
         }
     }
 
-    public static synchronized @TrickplaySetting int getTrickplaySetting(Context context) {
+    @TrickplaySetting
+    public static synchronized int getTrickplaySetting(Context context) {
         SoftPreconditions.checkState(sInitialized);
         if (useContentProvider(context)) {
             return sPreferenceValues.getInt(PREFS_KEY_TRICKPLAY_SETTING, TRICKPLAY_SETTING_NOT_SET);
diff --git a/tuner/sampletunertvinput/Android.bp b/tuner/sampletunertvinput/Android.bp
index ba08611..4e5900b 100644
--- a/tuner/sampletunertvinput/Android.bp
+++ b/tuner/sampletunertvinput/Android.bp
@@ -29,7 +29,6 @@
     platform_apis: true,
     system_ext_specific: true,
 
-
     privileged: true,
     certificate: "platform",
     // product_specific: true,
@@ -63,5 +62,13 @@
         "tv-auto-value",
         "tv-auto-factory",
     ],
+    required: ["com.android.tv.samples.sampletunertvinput.xml"],
     // min_sdk_version: "29",
 }
+
+prebuilt_etc {
+    name: "com.android.tv.samples.sampletunertvinput.xml",
+    sub_dir: "permissions",
+    src: "com.android.tv.samples.sampletunertvinput.xml",
+    system_ext_specific: true,
+}
diff --git a/tuner/sampletunertvinput/com.android.tv.samples.sampletunertvinput.xml b/tuner/sampletunertvinput/com.android.tv.samples.sampletunertvinput.xml
new file mode 100644
index 0000000..d98e36c
--- /dev/null
+++ b/tuner/sampletunertvinput/com.android.tv.samples.sampletunertvinput.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+    <privapp-permissions package="com.android.tv.samples.sampletunertvinput">
+        <permission name="android.permission.ACCESS_TV_DESCRAMBLER"/>
+        <permission name="android.permission.ACCESS_TV_TUNER"/>
+        <permission name="android.permission.TUNER_RESOURCE_ACCESS"/>
+    </privapp-permissions>
+</permissions>
diff --git a/tuner/sampletunertvinput/src/com/android/tv/samples/sampletunertvinput/SampleTunerTvInputService.java b/tuner/sampletunertvinput/src/com/android/tv/samples/sampletunertvinput/SampleTunerTvInputService.java
index e86ced1..03e7965 100644
--- a/tuner/sampletunertvinput/src/com/android/tv/samples/sampletunertvinput/SampleTunerTvInputService.java
+++ b/tuner/sampletunertvinput/src/com/android/tv/samples/sampletunertvinput/SampleTunerTvInputService.java
@@ -5,6 +5,7 @@
 import android.content.Context;
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodec.LinearBlock;
 import android.media.MediaFormat;
 import android.media.tv.tuner.dvr.DvrPlayback;
 import android.media.tv.tuner.dvr.DvrSettings;
@@ -53,13 +54,13 @@
     private static final int PACKET_SIZE = 188;
 
     private static final int TIMEOUT_US = 100000;
-    private static final boolean SAVE_DATA = true;
-    private static final String ES_PATH = "/data/local/tmp/test.es";
+    private static final boolean SAVE_DATA = false;
+    private static final String ES_FILE_NAME = "test.es";
     private static final MediaFormat VIDEO_FORMAT;
 
     static {
         // format extracted for the specific input file
-        VIDEO_FORMAT = MediaFormat.createVideoFormat("video/avc", 320, 240);
+        VIDEO_FORMAT = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 320, 240);
         VIDEO_FORMAT.setInteger(MediaFormat.KEY_TRACK_ID, 1);
         VIDEO_FORMAT.setLong(MediaFormat.KEY_DURATION, 9933333);
         VIDEO_FORMAT.setInteger(MediaFormat.KEY_LEVEL, 32);
@@ -134,9 +135,11 @@
             }
             if (mDvr != null) {
                 mDvr.close();
+                mDvr = null;
             }
             if (mTuner != null) {
                 mTuner.close();
+                mTuner = null;
             }
             mDataQueue = null;
             mSavedData = null;
@@ -243,9 +246,9 @@
                         public void onFilterStatusChanged(Filter filter, int status) {
                             if (DEBUG) {
                                 Log.d(TAG, "onFilterEvent video, status=" + status);
-                                if (status == Filter.STATUS_DATA_READY) {
-                                    mDataReady = true;
-                                }
+                            }
+                            if (status == Filter.STATUS_DATA_READY) {
+                                mDataReady = true;
                             }
                         }
                     });
@@ -275,7 +278,8 @@
             if (DEBUG) {
                 Log.d(TAG, "config res=" + res);
             }
-            File file = new File(ES_PATH);
+            String testFile = mContext.getFilesDir().getAbsolutePath() + "/" + ES_FILE_NAME;
+            File file = new File(testFile);
             if (file.exists()) {
                 try {
                     dvr.setFileDescriptor(
@@ -323,10 +327,10 @@
                 mMediaCodec = null;
             }
             try {
-                mMediaCodec = MediaCodec.createDecoderByType("video/avc");
+                mMediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
                 mMediaCodec.configure(VIDEO_FORMAT, mSurface, null, 0);
             } catch (IOException e) {
-                Log.e(TAG, "Error: " + e.getMessage());
+                Log.e(TAG, "Error in initCodec: " + e.getMessage());
             }
 
             if (mMediaCodec == null) {
@@ -357,23 +361,41 @@
                 while (!Thread.interrupted()) {
                     if (!mDataReady) {
                         Thread.sleep(100);
+                        continue;
                     }
                     if (!mDataQueue.isEmpty()) {
-                        if (queueCodecInputBuffer(mDataQueue.getFirst())) {
+                        if (handleDataBuffer(mDataQueue.getFirst())) {
                             // data consumed, remove.
                             mDataQueue.pollFirst();
                         }
-                    } else if (SAVE_DATA) {
+                    }
+                    if (SAVE_DATA) {
                         mDataQueue.addAll(mSavedData);
                     }
-                    releaseCodecOutputBuffer();
                 }
             } catch (Exception e) {
-                Log.e(TAG, "Error: " + e.getMessage());
+                Log.e(TAG, "Error in decodeInternal: " + e.getMessage());
             }
         }
 
-        private boolean queueCodecInputBuffer(MediaEvent mediaEvent) {
+        private boolean handleDataBuffer(MediaEvent mediaEvent) {
+            if (mediaEvent.getLinearBlock() == null) {
+                if (DEBUG) Log.d(TAG, "getLinearBlock() == null");
+                return true;
+            }
+            boolean success = false;
+            LinearBlock block = mediaEvent.getLinearBlock();
+            if (queueCodecInputBuffer(block, mediaEvent.getDataLength(), mediaEvent.getOffset(),
+                                  mediaEvent.getPts())) {
+                releaseCodecOutputBuffer();
+                success = true;
+            }
+            mediaEvent.release();
+            return success;
+        }
+
+        private boolean queueCodecInputBuffer(LinearBlock block, long sampleSize,
+                                              long offset, long pts) {
             int res = mMediaCodec.dequeueInputBuffer(TIMEOUT_US);
             if (res >= 0) {
                 ByteBuffer buffer = mMediaCodec.getInputBuffer(res);
@@ -381,13 +403,9 @@
                     throw new RuntimeException("Null decoder input buffer");
                 }
 
-                ByteBuffer data = mediaEvent.getLinearBlock().map();
-                int sampleSize = (int) mediaEvent.getDataLength();
-                int offset = (int) mediaEvent.getOffset();
-                long pts = mediaEvent.getPts();
-
+                ByteBuffer data = block.map();
                 if (offset > 0 && offset < data.limit()) {
-                    data.position(offset);
+                    data.position((int) offset);
                 } else {
                     data.position(0);
                 }
@@ -407,14 +425,21 @@
                             + " size="
                             + (data.limit() - data.position()));
                 }
-                while (data.position() < data.limit()) {
-                    // fill codec input buffer
-                    buffer.put(data.get());
+                // fill codec input buffer
+                int size = sampleSize > data.limit() ? data.limit() : (int) sampleSize;
+                if (DEBUG) Log.d(TAG, "limit " + data.limit() + " sampleSize " + sampleSize);
+                if (data.hasArray()) {
+                    Log.d(TAG, "hasArray");
+                    buffer.put(data.array(), 0, size);
+                } else {
+                    byte[] array = new byte[size];
+                    data.get(array, 0, size);
+                    buffer.put(array, 0, size);
                 }
 
-                mMediaCodec.queueInputBuffer(res, 0, sampleSize, pts, 0);
+                mMediaCodec.queueInputBuffer(res, 0, (int) sampleSize, pts, 0);
             } else {
-                Log.d(TAG, "queueCodecInputBuffer res=" + res);
+                if (DEBUG) Log.d(TAG, "queueCodecInputBuffer res=" + res);
                 return false;
             }
             return true;
@@ -447,4 +472,4 @@
         }
 
     }
-}
\ No newline at end of file
+}