Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5927ae8 authored by Chong Zhang's avatar Chong Zhang
Browse files

MediaCas: add framework APIs

Java API changes to support MediaCas framework.

Also add partial-frame related enums to MediaCodec,
MediaCodecInfo, and MediaExtractor as a way to indicate
a input frame contains partial data.

Test: basic test app and test plugin to execise the code path;
impelenting playback of CAS-secured MPEG2TS streams, including
a Widevine-based CAS plugin, locally modified ExoPlayer and
Android TV Tuner input.

bug: 22804304
Change-Id: Ia4ba1d4046f7588e42bfb21e726390457d2fc8e3
parent ab7bc7af
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -409,6 +409,10 @@ LOCAL_SRC_FILES += \
	location/java/android/location/INetInitiatedListener.aidl \
	location/java/com/android/internal/location/ILocationProvider.aidl \
	media/java/android/media/IAudioService.aidl \
	media/java/android/media/ICas.aidl \
	media/java/android/media/ICasListener.aidl \
	media/java/android/media/IDescrambler.aidl \
	media/java/android/media/IMediaCasService.aidl \
	media/java/android/media/IAudioFocusDispatcher.aidl \
	media/java/android/media/IAudioRoutesObserver.aidl \
	media/java/android/media/IMediaHTTPConnection.aidl \
+52 −0
Original line number Diff line number Diff line
@@ -21467,8 +21467,42 @@ package android.media {
    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
  }
  public final class MediaCas {
    ctor public MediaCas(int) throws android.media.UnsupportedCasException;
    method public void closeSession(byte[]);
    method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
    method public static boolean isSystemIdSupported(int);
    method public byte[] openSession(int);
    method public byte[] openSession(int, int);
    method public void processEcm(byte[], byte[], int, int);
    method public void processEcm(byte[], byte[]);
    method public void processEmm(byte[], int, int);
    method public void processEmm(byte[]);
    method public void provision(java.lang.String);
    method public void refreshEntitlements(int, byte[]);
    method public void release();
    method public void sendEvent(int, int, byte[]);
    method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
    method public void setPrivateData(byte[]);
    method public void setSessionPrivateData(byte[], byte[]);
  }
  public static abstract interface MediaCas.EventListener {
    method public abstract void onEvent(android.media.MediaCas, int, int, byte[]);
  }
  public static class MediaCas.PluginDescriptor {
    method public java.lang.String getName();
    method public int getSystemId();
  }
  public class MediaCasException extends java.lang.Exception {
    ctor public MediaCasException(java.lang.String);
  }
  public final class MediaCodec {
    method public void configure(android.media.MediaFormat, android.view.Surface, android.media.MediaCrypto, int);
    method public void configure(android.media.MediaFormat, android.view.Surface, int, android.media.MediaDescrambler);
    method public static android.media.MediaCodec createByCodecName(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
@@ -21508,6 +21542,7 @@ package android.media {
    field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
    field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
    field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
    field public static final int BUFFER_FLAG_PARTIAL_FRAME = 8; // 0x8
    field public static final deprecated int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
    field public static final int CONFIGURE_FLAG_ENCODE = 1; // 0x1
    field public static final int CRYPTO_MODE_AES_CBC = 2; // 0x2
@@ -21664,6 +21699,7 @@ package android.media {
    field public static final deprecated int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
    field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
    field public static final java.lang.String FEATURE_IntraRefresh = "intra-refresh";
    field public static final java.lang.String FEATURE_PartialFrame = "partial-frame";
    field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
    field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
    field public int[] colorFormats;
@@ -21888,6 +21924,14 @@ package android.media {
    method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
  }
  public final class MediaDescrambler {
    ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException;
    method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
    method public final void release();
    method public final boolean requiresSecureDecoderComponent(java.lang.String);
    method public final void setMediaCasSession(byte[]);
  }
  public class MediaDescription implements android.os.Parcelable {
    method public int describeContents();
    method public java.lang.CharSequence getDescription();
@@ -22044,8 +22088,10 @@ package android.media {
    method public final void setDataSource(android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
    method public final void setDataSource(java.io.FileDescriptor) throws java.io.IOException;
    method public final void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException;
    method public final void setMediaCas(android.media.MediaCas);
    method public void unselectTrack(int);
    field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
    field public static final int SAMPLE_FLAG_PARTIAL_FRAME = 4; // 0x4
    field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
    field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2
    field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1
@@ -22142,6 +22188,7 @@ package android.media {
    field public static final java.lang.String MIMETYPE_AUDIO_OPUS = "audio/opus";
    field public static final java.lang.String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
    field public static final java.lang.String MIMETYPE_AUDIO_RAW = "audio/raw";
    field public static final java.lang.String MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
    field public static final java.lang.String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
    field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
    field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
@@ -22152,6 +22199,7 @@ package android.media {
    field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
    field public static final java.lang.String MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
    field public static final java.lang.String MIMETYPE_VIDEO_RAW = "video/raw";
    field public static final java.lang.String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
    field public static final java.lang.String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
    field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
  }
@@ -23123,6 +23171,10 @@ package android.media {
    field public static final int TONE_SUP_RINGTONE = 23; // 0x17
  }
  public final class UnsupportedCasException extends android.media.MediaCasException {
    ctor public UnsupportedCasException(java.lang.String);
  }
  public final class UnsupportedSchemeException extends android.media.MediaDrmException {
    ctor public UnsupportedSchemeException(java.lang.String);
  }
+52 −0
Original line number Diff line number Diff line
@@ -23155,8 +23155,42 @@ package android.media {
    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
  }
  public final class MediaCas {
    ctor public MediaCas(int) throws android.media.UnsupportedCasException;
    method public void closeSession(byte[]);
    method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
    method public static boolean isSystemIdSupported(int);
    method public byte[] openSession(int);
    method public byte[] openSession(int, int);
    method public void processEcm(byte[], byte[], int, int);
    method public void processEcm(byte[], byte[]);
    method public void processEmm(byte[], int, int);
    method public void processEmm(byte[]);
    method public void provision(java.lang.String);
    method public void refreshEntitlements(int, byte[]);
    method public void release();
    method public void sendEvent(int, int, byte[]);
    method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
    method public void setPrivateData(byte[]);
    method public void setSessionPrivateData(byte[], byte[]);
  }
  public static abstract interface MediaCas.EventListener {
    method public abstract void onEvent(android.media.MediaCas, int, int, byte[]);
  }
  public static class MediaCas.PluginDescriptor {
    method public java.lang.String getName();
    method public int getSystemId();
  }
  public class MediaCasException extends java.lang.Exception {
    ctor public MediaCasException(java.lang.String);
  }
  public final class MediaCodec {
    method public void configure(android.media.MediaFormat, android.view.Surface, android.media.MediaCrypto, int);
    method public void configure(android.media.MediaFormat, android.view.Surface, int, android.media.MediaDescrambler);
    method public static android.media.MediaCodec createByCodecName(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
@@ -23196,6 +23230,7 @@ package android.media {
    field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
    field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
    field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
    field public static final int BUFFER_FLAG_PARTIAL_FRAME = 8; // 0x8
    field public static final deprecated int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
    field public static final int CONFIGURE_FLAG_ENCODE = 1; // 0x1
    field public static final int CRYPTO_MODE_AES_CBC = 2; // 0x2
@@ -23352,6 +23387,7 @@ package android.media {
    field public static final deprecated int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
    field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
    field public static final java.lang.String FEATURE_IntraRefresh = "intra-refresh";
    field public static final java.lang.String FEATURE_PartialFrame = "partial-frame";
    field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
    field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
    field public int[] colorFormats;
@@ -23576,6 +23612,14 @@ package android.media {
    method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
  }
  public final class MediaDescrambler {
    ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException;
    method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
    method public final void release();
    method public final boolean requiresSecureDecoderComponent(java.lang.String);
    method public final void setMediaCasSession(byte[]);
  }
  public class MediaDescription implements android.os.Parcelable {
    method public int describeContents();
    method public java.lang.CharSequence getDescription();
@@ -23732,8 +23776,10 @@ package android.media {
    method public final void setDataSource(android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
    method public final void setDataSource(java.io.FileDescriptor) throws java.io.IOException;
    method public final void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException;
    method public final void setMediaCas(android.media.MediaCas);
    method public void unselectTrack(int);
    field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
    field public static final int SAMPLE_FLAG_PARTIAL_FRAME = 4; // 0x4
    field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
    field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2
    field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1
@@ -23830,6 +23876,7 @@ package android.media {
    field public static final java.lang.String MIMETYPE_AUDIO_OPUS = "audio/opus";
    field public static final java.lang.String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
    field public static final java.lang.String MIMETYPE_AUDIO_RAW = "audio/raw";
    field public static final java.lang.String MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
    field public static final java.lang.String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
    field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
    field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
@@ -23840,6 +23887,7 @@ package android.media {
    field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
    field public static final java.lang.String MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
    field public static final java.lang.String MIMETYPE_VIDEO_RAW = "video/raw";
    field public static final java.lang.String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
    field public static final java.lang.String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
    field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
  }
@@ -24822,6 +24870,10 @@ package android.media {
    field public static final int TONE_SUP_RINGTONE = 23; // 0x17
  }
  public final class UnsupportedCasException extends android.media.MediaCasException {
    ctor public UnsupportedCasException(java.lang.String);
  }
  public final class UnsupportedSchemeException extends android.media.MediaDrmException {
    ctor public UnsupportedSchemeException(java.lang.String);
  }
+52 −0
Original line number Diff line number Diff line
@@ -21563,8 +21563,42 @@ package android.media {
    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
  }
  public final class MediaCas {
    ctor public MediaCas(int) throws android.media.UnsupportedCasException;
    method public void closeSession(byte[]);
    method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
    method public static boolean isSystemIdSupported(int);
    method public byte[] openSession(int);
    method public byte[] openSession(int, int);
    method public void processEcm(byte[], byte[], int, int);
    method public void processEcm(byte[], byte[]);
    method public void processEmm(byte[], int, int);
    method public void processEmm(byte[]);
    method public void provision(java.lang.String);
    method public void refreshEntitlements(int, byte[]);
    method public void release();
    method public void sendEvent(int, int, byte[]);
    method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
    method public void setPrivateData(byte[]);
    method public void setSessionPrivateData(byte[], byte[]);
  }
  public static abstract interface MediaCas.EventListener {
    method public abstract void onEvent(android.media.MediaCas, int, int, byte[]);
  }
  public static class MediaCas.PluginDescriptor {
    method public java.lang.String getName();
    method public int getSystemId();
  }
  public class MediaCasException extends java.lang.Exception {
    ctor public MediaCasException(java.lang.String);
  }
  public final class MediaCodec {
    method public void configure(android.media.MediaFormat, android.view.Surface, android.media.MediaCrypto, int);
    method public void configure(android.media.MediaFormat, android.view.Surface, int, android.media.MediaDescrambler);
    method public static android.media.MediaCodec createByCodecName(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
@@ -21604,6 +21638,7 @@ package android.media {
    field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
    field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
    field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
    field public static final int BUFFER_FLAG_PARTIAL_FRAME = 8; // 0x8
    field public static final deprecated int BUFFER_FLAG_SYNC_FRAME = 1; // 0x1
    field public static final int CONFIGURE_FLAG_ENCODE = 1; // 0x1
    field public static final int CRYPTO_MODE_AES_CBC = 2; // 0x2
@@ -21760,6 +21795,7 @@ package android.media {
    field public static final deprecated int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
    field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
    field public static final java.lang.String FEATURE_IntraRefresh = "intra-refresh";
    field public static final java.lang.String FEATURE_PartialFrame = "partial-frame";
    field public static final java.lang.String FEATURE_SecurePlayback = "secure-playback";
    field public static final java.lang.String FEATURE_TunneledPlayback = "tunneled-playback";
    field public int[] colorFormats;
@@ -21984,6 +22020,14 @@ package android.media {
    method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
  }
  public final class MediaDescrambler {
    ctor public MediaDescrambler(int) throws android.media.UnsupportedCasException;
    method public final int descramble(java.nio.ByteBuffer, int, java.nio.ByteBuffer, int, android.media.MediaCodec.CryptoInfo);
    method public final void release();
    method public final boolean requiresSecureDecoderComponent(java.lang.String);
    method public final void setMediaCasSession(byte[]);
  }
  public class MediaDescription implements android.os.Parcelable {
    method public int describeContents();
    method public java.lang.CharSequence getDescription();
@@ -22140,8 +22184,10 @@ package android.media {
    method public final void setDataSource(android.content.res.AssetFileDescriptor) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
    method public final void setDataSource(java.io.FileDescriptor) throws java.io.IOException;
    method public final void setDataSource(java.io.FileDescriptor, long, long) throws java.io.IOException;
    method public final void setMediaCas(android.media.MediaCas);
    method public void unselectTrack(int);
    field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
    field public static final int SAMPLE_FLAG_PARTIAL_FRAME = 4; // 0x4
    field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
    field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2
    field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1
@@ -22238,6 +22284,7 @@ package android.media {
    field public static final java.lang.String MIMETYPE_AUDIO_OPUS = "audio/opus";
    field public static final java.lang.String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
    field public static final java.lang.String MIMETYPE_AUDIO_RAW = "audio/raw";
    field public static final java.lang.String MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
    field public static final java.lang.String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
    field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
    field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
@@ -22248,6 +22295,7 @@ package android.media {
    field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
    field public static final java.lang.String MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
    field public static final java.lang.String MIMETYPE_VIDEO_RAW = "video/raw";
    field public static final java.lang.String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
    field public static final java.lang.String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
    field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
  }
@@ -23219,6 +23267,10 @@ package android.media {
    field public static final int TONE_SUP_RINGTONE = 23; // 0x17
  }
  public final class UnsupportedCasException extends android.media.MediaCasException {
    ctor public UnsupportedCasException(java.lang.String);
  }
  public final class UnsupportedSchemeException extends android.media.MediaDrmException {
    ctor public UnsupportedSchemeException(java.lang.String);
  }
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 android.media;

import android.media.MediaCas;

/** @hide */
interface ICas {
    void setPrivateData(in byte[] pvtData);
    byte[] openSession(int program_number);
    byte[] openSessionForStream(int program_number, int elementary_PID);
    void closeSession(in byte[] sessionId);
    void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
    void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
    void processEmm(in MediaCas.ParcelableCasData emm);
    void sendEvent(int event, int arg, in @nullable byte[] eventData);
    void provision(String provisionString);
    void refreshEntitlements(int refreshType, in @nullable byte[] refreshData);
    void release();
}
 No newline at end of file
Loading