Loading Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -326,8 +326,9 @@ java_library { "framework-protos", "game-driver-protos", "android.hidl.base-V1.0-java", "android.hardware.cas-V1.1-java", "android.hardware.cas-V1.0-java", "android.hardware.cas-V1.1-java", "android.hardware.cas-V1.2-java", "android.hardware.contexthub-V1.0-java", "android.hardware.gnss-V1.0-java", "android.hardware.health-V1.0-java-constants", Loading api/current.txt +46 −0 Original line number Diff line number Diff line Loading @@ -24789,11 +24789,13 @@ package android.media { public final class MediaCas implements java.lang.AutoCloseable { ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException; ctor public MediaCas(int, @Nullable String, int) throws android.media.MediaCasException.UnsupportedCasException; method public void close(); method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins(); method protected void finalize(); method public static boolean isSystemIdSupported(int); method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException; method @Nullable public android.media.MediaCas.Session openSession(int, int) throws android.media.MediaCasException; method public void processEmm(@NonNull byte[], int, int) throws android.media.MediaCasException; method public void processEmm(@NonNull byte[]) throws android.media.MediaCasException; method public void provision(@NonNull String) throws android.media.MediaCasException; Loading @@ -24801,10 +24803,32 @@ package android.media { method public void sendEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException; method public void setEventListener(@Nullable android.media.MediaCas.EventListener, @Nullable android.os.Handler); method public void setPrivateData(@NonNull byte[]) throws android.media.MediaCasException; field public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = 0; // 0x0 field public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = 1; // 0x1 field public static final int SCRAMBLING_MODE_AES128 = 9; // 0x9 field public static final int SCRAMBLING_MODE_AES_ECB = 10; // 0xa field public static final int SCRAMBLING_MODE_AES_SCTE52 = 11; // 0xb field public static final int SCRAMBLING_MODE_DVB_CISSA_V1 = 6; // 0x6 field public static final int SCRAMBLING_MODE_DVB_CSA1 = 1; // 0x1 field public static final int SCRAMBLING_MODE_DVB_CSA2 = 2; // 0x2 field public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE = 5; // 0x5 field public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL = 4; // 0x4 field public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD = 3; // 0x3 field public static final int SCRAMBLING_MODE_DVB_IDSA = 7; // 0x7 field public static final int SCRAMBLING_MODE_MULTI2 = 8; // 0x8 field public static final int SCRAMBLING_MODE_RESERVED = 0; // 0x0 field public static final int SCRAMBLING_MODE_TDES_ECB = 12; // 0xc field public static final int SCRAMBLING_MODE_TDES_SCTE52 = 13; // 0xd field public static final int SESSION_USAGE_LIVE = 0; // 0x0 field public static final int SESSION_USAGE_PLAYBACK = 1; // 0x1 field public static final int SESSION_USAGE_RECORD = 2; // 0x2 field public static final int SESSION_USAGE_TIMESHIFT = 3; // 0x3 } public static interface MediaCas.EventListener { method public void onEvent(@NonNull android.media.MediaCas, int, int, @Nullable byte[]); method public default void onPluginStatusUpdate(@NonNull android.media.MediaCas, int, int); method public default void onResourceLost(@NonNull android.media.MediaCas); method public default void onSessionEvent(@NonNull android.media.MediaCas, @NonNull android.media.MediaCas.Session, int, int, @Nullable byte[]); } Loading @@ -24815,6 +24839,7 @@ package android.media { public final class MediaCas.Session implements java.lang.AutoCloseable { method public void close(); method @NonNull public byte[] getSessionId(); method public void processEcm(@NonNull byte[], int, int) throws android.media.MediaCasException; method public void processEcm(@NonNull byte[]) throws android.media.MediaCasException; method public void sendSessionEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException; Loading @@ -24827,6 +24852,9 @@ package android.media { public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException { } public static final class MediaCasException.InsufficientResourceException extends android.media.MediaCasException { } public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException { } Loading Loading @@ -28813,6 +28841,19 @@ package android.media.tv { field public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1; // 0x1 field public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 4; // 0x4 field public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; // 0x3 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT = 16; // 0x10 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID = 15; // 0xf field public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE = 14; // 0xe field public static final int VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 7; // 0x7 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED = 10; // 0xa field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION = 11; // 0xb field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING = 12; // 0xc field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD = 13; // 0xd field public static final int VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED = 8; // 0x8 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING = 17; // 0x11 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN = 18; // 0x12 field public static final int VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 6; // 0x6 field public static final int VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 5; // 0x5 field public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; // 0x1 field public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = 0; // 0x0 field public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; // 0x2 Loading @@ -28834,6 +28875,11 @@ package android.media.tv { method @Nullable public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(@NonNull String, @NonNull String); method @Nullable public abstract android.media.tv.TvInputService.Session onCreateSession(String); method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String); field public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100; // 0x64 field public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400; // 0x190 field public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300; // 0x12c field public static final int PRIORITY_HINT_USE_CASE_TYPE_RECORD = 500; // 0x1f4 field public static final int PRIORITY_HINT_USE_CASE_TYPE_SCAN = 200; // 0xc8 field public static final String SERVICE_INTERFACE = "android.media.tv.TvInputService"; field public static final String SERVICE_META_DATA = "android.media.tv.input"; } media/java/android/media/MediaCas.java +303 −19 Original line number Diff line number Diff line Loading @@ -16,13 +16,15 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.cas.V1_0.HidlCasPluginDescriptor; import android.hardware.cas.V1_0.ICas; import android.hardware.cas.V1_0.IMediaCasService; import android.hardware.cas.V1_1.ICasListener; import android.hardware.cas.V1_2.ICasListener; import android.media.MediaCasException.*; import android.media.tv.TvInputService.PriorityHintUseCaseType; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; Loading @@ -34,6 +36,8 @@ import android.os.RemoteException; import android.util.Log; import android.util.Singleton; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; /** Loading Loading @@ -100,28 +104,185 @@ public final class MediaCas implements AutoCloseable { private static final String TAG = "MediaCas"; private ICas mICas; private android.hardware.cas.V1_1.ICas mICasV11; private android.hardware.cas.V1_2.ICas mICasV12; private EventListener mListener; private HandlerThread mHandlerThread; private EventHandler mEventHandler; private @PriorityHintUseCaseType int mPriorityHint; private String mTvInputServiceSessionId; /** * Scrambling modes used to open cas sessions. * * @hide */ @IntDef(prefix = "SCRAMBLING_MODE_", value = {SCRAMBLING_MODE_RESERVED, SCRAMBLING_MODE_DVB_CSA1, SCRAMBLING_MODE_DVB_CSA2, SCRAMBLING_MODE_DVB_CSA3_STANDARD, SCRAMBLING_MODE_DVB_CSA3_MINIMAL, SCRAMBLING_MODE_DVB_CSA3_ENHANCE, SCRAMBLING_MODE_DVB_CISSA_V1, SCRAMBLING_MODE_DVB_IDSA, SCRAMBLING_MODE_MULTI2, SCRAMBLING_MODE_AES128, SCRAMBLING_MODE_AES_ECB, SCRAMBLING_MODE_AES_SCTE52, SCRAMBLING_MODE_TDES_ECB, SCRAMBLING_MODE_TDES_SCTE52}) @Retention(RetentionPolicy.SOURCE) public @interface ScramblingMode {} /** * DVB (Digital Video Broadcasting) reserved mode. */ public static final int SCRAMBLING_MODE_RESERVED = android.hardware.cas.V1_2.ScramblingMode.RESERVED; /** * DVB (Digital Video Broadcasting) Common Scrambling Algorithm (CSA) 1. */ public static final int SCRAMBLING_MODE_DVB_CSA1 = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA1; /** * DVB CSA 2. */ public static final int SCRAMBLING_MODE_DVB_CSA2 = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA2; /** * DVB CSA 3 in standard mode. */ public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_STANDARD; /** * DVB CSA 3 in minimally enhanced mode. */ public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_MINIMAL; /** * DVB CSA 3 in fully enhanced mode. */ public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_ENHANCE; /** * DVB Common IPTV Software-oriented Scrambling Algorithm (CISSA) Version 1. */ public static final int SCRAMBLING_MODE_DVB_CISSA_V1 = android.hardware.cas.V1_2.ScramblingMode.DVB_CISSA_V1; /** * ATIS-0800006 IIF Default Scrambling Algorithm (IDSA). */ public static final int SCRAMBLING_MODE_DVB_IDSA = android.hardware.cas.V1_2.ScramblingMode.DVB_IDSA; /** * A symmetric key algorithm. */ public static final int SCRAMBLING_MODE_MULTI2 = android.hardware.cas.V1_2.ScramblingMode.MULTI2; /** * Advanced Encryption System (AES) 128-bit Encryption mode. */ public static final int SCRAMBLING_MODE_AES128 = android.hardware.cas.V1_2.ScramblingMode.AES128; /** * Advanced Encryption System (AES) Electronic Code Book (ECB) mode. */ public static final int SCRAMBLING_MODE_AES_ECB = android.hardware.cas.V1_2.ScramblingMode.AES_ECB; /** * Advanced Encryption System (AES) Society of Cable Telecommunications Engineers (SCTE) 52 * mode. */ public static final int SCRAMBLING_MODE_AES_SCTE52 = android.hardware.cas.V1_2.ScramblingMode.AES_SCTE52; /** * Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode. */ public static final int SCRAMBLING_MODE_TDES_ECB = android.hardware.cas.V1_2.ScramblingMode.TDES_ECB; /** * Triple Data Encryption Algorithm (TDES) Society of Cable Telecommunications Engineers (SCTE) * 52 mode. */ public static final int SCRAMBLING_MODE_TDES_SCTE52 = android.hardware.cas.V1_2.ScramblingMode.TDES_SCTE52; /** * Usages used to open cas sessions. * * @hide */ @IntDef(prefix = "SESSION_USAGE_", value = {SESSION_USAGE_LIVE, SESSION_USAGE_PLAYBACK, SESSION_USAGE_RECORD, SESSION_USAGE_TIMESHIFT}) @Retention(RetentionPolicy.SOURCE) public @interface SessionUsage {} /** * Cas session is used to descramble live streams. */ public static final int SESSION_USAGE_LIVE = android.hardware.cas.V1_2.SessionIntent.LIVE; /** * Cas session is used to descramble recoreded streams. */ public static final int SESSION_USAGE_PLAYBACK = android.hardware.cas.V1_2.SessionIntent.PLAYBACK; /** * Cas session is used to descramble live streams and encrypt local recorded content */ public static final int SESSION_USAGE_RECORD = android.hardware.cas.V1_2.SessionIntent.RECORD; /** * Cas session is used to descramble live streams , encrypt local recorded content and playback * local encrypted content. */ public static final int SESSION_USAGE_TIMESHIFT = android.hardware.cas.V1_2.SessionIntent.TIMESHIFT; /** * Plugin status events sent from cas system. * * @hide */ @IntDef(prefix = "PLUGIN_STATUS_", value = {PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED, PLUGIN_STATUS_SESSION_NUMBER_CHANGED}) @Retention(RetentionPolicy.SOURCE) public @interface PluginStatus {} /** * The event to indicate that the status of CAS system is changed by the removal or insertion of * physical CAS modules. */ public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = android.hardware.cas.V1_2.StatusEvent.PLUGIN_PHYSICAL_MODULE_CHANGED; /** * The event to indicate that the number of CAS system's session is changed. */ public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = android.hardware.cas.V1_2.StatusEvent.PLUGIN_SESSION_NUMBER_CHANGED; private static final Singleton<IMediaCasService> sService = new Singleton<IMediaCasService>() { @Override protected IMediaCasService create() { try { Log.d(TAG, "Tried to get cas@1.1 service"); Log.d(TAG, "Trying to get cas@1.2 service"); android.hardware.cas.V1_2.IMediaCasService serviceV12 = android.hardware.cas.V1_2.IMediaCasService.getService(true /*wait*/); if (serviceV12 != null) { return serviceV12; } } catch (Exception eV1_2) { Log.d(TAG, "Failed to get cas@1.2 service"); } try { Log.d(TAG, "Trying to get cas@1.1 service"); android.hardware.cas.V1_1.IMediaCasService serviceV11 = android.hardware.cas.V1_1.IMediaCasService.getService(true /*wait*/); if (serviceV11 != null) { return serviceV11; } } catch (Exception eV1_1) { Log.d(TAG, "Failed to get cas@1.1 service"); } try { Log.d(TAG, "Tried to get cas@1.0 service"); Log.d(TAG, "Trying to get cas@1.0 service"); return IMediaCasService.getService(true /*wait*/); } catch (Exception eV1_0) { Log.d(TAG, "Failed to get cas@1.0 service"); } } return null; } }; Loading @@ -139,6 +300,7 @@ public final class MediaCas implements AutoCloseable { private void cleanupAndRethrowIllegalState() { mICas = null; mICasV11 = null; mICasV12 = null; throw new IllegalStateException(); } Loading @@ -146,6 +308,8 @@ public final class MediaCas implements AutoCloseable { private static final int MSG_CAS_EVENT = 0; private static final int MSG_CAS_SESSION_EVENT = 1; private static final int MSG_CAS_STATUS_EVENT = 2; private static final int MSG_CAS_RESOURCE_LOST = 3; private static final String SESSION_KEY = "sessionId"; private static final String DATA_KEY = "data"; Loading @@ -164,6 +328,10 @@ public final class MediaCas implements AutoCloseable { mListener.onSessionEvent(MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, bundle.getByteArray(DATA_KEY)); } else if (msg.what == MSG_CAS_STATUS_EVENT) { mListener.onPluginStatusUpdate(MediaCas.this, msg.arg1, msg.arg2); } else if (msg.what == MSG_CAS_RESOURCE_LOST) { mListener.onResourceLost(MediaCas.this); } } } Loading @@ -189,6 +357,12 @@ public final class MediaCas implements AutoCloseable { msg.setData(bundle); mEventHandler.sendMessage(msg); } @Override public void onStatusUpdate(byte status, int arg) throws RemoteException { mEventHandler.sendMessage(mEventHandler.obtainMessage( EventHandler.MSG_CAS_STATUS_EVENT, status, arg)); } }; /** * Describe a CAS plugin with its CA_system_ID and string name. Loading Loading @@ -257,7 +431,7 @@ public final class MediaCas implements AutoCloseable { final ArrayList<Byte> mSessionId; Session(@NonNull ArrayList<Byte> sessionId) { mSessionId = sessionId; mSessionId = new ArrayList<Byte>(sessionId); } /** Loading Loading @@ -363,6 +537,19 @@ public final class MediaCas implements AutoCloseable { } } /** * Get Session Id. * * @return session Id of the session. * * @throws IllegalStateException if the MediaCas instance is not valid. */ @NonNull public byte[] getSessionId() { validateInternalStates(); return toBytes(mSessionId); } /** * Close the session. * Loading Loading @@ -445,6 +632,9 @@ public final class MediaCas implements AutoCloseable { public MediaCas(int CA_system_id) throws UnsupportedCasException { try { IMediaCasService service = getService(); android.hardware.cas.V1_2.IMediaCasService serviceV12 = android.hardware.cas.V1_2.IMediaCasService.castFrom(service); if (serviceV12 == null) { android.hardware.cas.V1_1.IMediaCasService serviceV11 = android.hardware.cas.V1_1.IMediaCasService.castFrom(service); if (serviceV11 == null) { Loading @@ -454,6 +644,12 @@ public final class MediaCas implements AutoCloseable { Log.d(TAG, "Used cas@1.1 interface to create plugin"); mICas = mICasV11 = serviceV11.createPluginExt(CA_system_id, mBinder); } } else { Log.d(TAG, "Used cas@1.2 interface to create plugin"); mICas = mICasV11 = mICasV12 = android.hardware.cas.V1_2.ICas .castFrom(serviceV12.createPluginExt(CA_system_id, mBinder)); } } catch(Exception e) { Log.e(TAG, "Failed to create plugin: " + e); mICas = null; Loading @@ -465,6 +661,24 @@ public final class MediaCas implements AutoCloseable { } } /** * Instantiate a CA system of the specified system id. * * @param casSystemId The system id of the CA system. * @param tvInputServiceSessionId The Id of the session opened in TV Input Service (TIS) * {@link android.media.tv.TvInputService#onCreateSession(String, String)} * @param priorityHint priority hint from the use case type for new created CAS system. * * @throws UnsupportedCasException if the device does not support the * specified CA system. */ public MediaCas(int casSystemId, @Nullable String tvInputServiceSessionId, @PriorityHintUseCaseType int priorityHint) throws UnsupportedCasException { this(casSystemId); mPriorityHint = priorityHint; mTvInputServiceSessionId = tvInputServiceSessionId; } IHwBinder getBinder() { validateInternalStates(); Loading @@ -476,6 +690,7 @@ public final class MediaCas implements AutoCloseable { * to receives scheme-specific notifications from a MediaCas instance. */ public interface EventListener { /** * Notify the listener of a scheme-specific event from the CA system. * Loading @@ -501,6 +716,27 @@ public final class MediaCas implements AutoCloseable { int event, int arg, @Nullable byte[] data) { Log.d(TAG, "Received MediaCas Session event"); } /** * Notify the listener that the cas plugin status is updated. * * @param mediaCas the MediaCas object to receive this event. * @param status the plugin status which is updated. * @param arg an integer whose meaning is specific to the status to be updated. */ default void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status, int arg) { Log.d(TAG, "Received MediaCas Plugin Status event"); } /** * Notify the listener that the session resources was lost. * * @param mediaCas the MediaCas object to receive this event. */ default void onResourceLost(@NonNull MediaCas mediaCas) { Log.d(TAG, "Received MediaCas Resource Reclaim event"); } } /** Loading Loading @@ -563,6 +799,20 @@ public final class MediaCas implements AutoCloseable { mSession = createFromSessionId(sessionId); } } private class OpenSession_1_2_Callback implements android.hardware.cas.V1_2.ICas.openSession_1_2Callback { public Session mSession; public int mStatus; @Override public void onValues(int status, ArrayList<Byte> sessionId) { mStatus = status; mSession = createFromSessionId(sessionId); } } /** * Open a session to descramble one or more streams scrambled by the * conditional access system. Loading @@ -587,6 +837,40 @@ public final class MediaCas implements AutoCloseable { return null; } /** * Open a session with usage and scrambling information, so that descrambler can be configured * to descramble one or more streams scrambled by the conditional access system. * * @param sessionUsage used for the created session. * @param scramblingMode used for the created session. * * @return session the newly opened session. * * @throws IllegalStateException if the MediaCas instance is not valid. * @throws MediaCasException for CAS-specific errors. * @throws MediaCasStateException for CAS-specific state exceptions. */ @Nullable public Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode) throws MediaCasException { validateInternalStates(); if (mICasV12 == null) { Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface"); throw new UnsupportedCasException("Open Session with scrambling mode is not supported"); } try { OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback(); mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb); MediaCasException.throwExceptionIfNeeded(cb.mStatus); return cb.mSession; } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } return null; } /** * Send a received EMM packet to the CA system. * Loading media/java/android/media/MediaCasException.java +12 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package android.media; import android.hardware.cas.V1_0.Status; import android.hardware.cas.V1_2.Status; /** * Base class for MediaCas exceptions Loading Loading @@ -85,4 +85,15 @@ public class MediaCasException extends Exception { super(detailMessage); } } /** * Exception thrown when an operation on a MediaCas object is attempted * and hardware resources are not sufficient to allocate, due to client's lower priority. */ public static final class InsufficientResourceException extends MediaCasException { /** @hide */ public InsufficientResourceException(String detailMessage) { super(detailMessage); } } } media/java/android/media/MediaCasStateException.java +55 −35 Original line number Diff line number Diff line Loading @@ -18,8 +18,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.cas.V1_0.Status; import android.hardware.cas.V1_2.Status; /** * Base class for MediaCas runtime exceptions Loading Loading @@ -78,6 +77,27 @@ public class MediaCasStateException extends IllegalStateException { case Status.ERROR_CAS_DECRYPT: diagnosticInfo = "Decrypt error"; break; case Status.ERROR_CAS_NEED_ACTIVATION: diagnosticInfo = "Need Activation"; break; case Status.ERROR_CAS_NEED_PAIRING: diagnosticInfo = "Need Pairing"; break; case Status.ERROR_CAS_NO_CARD: diagnosticInfo = "No Card"; break; case Status.ERROR_CAS_CARD_MUTE: diagnosticInfo = "Card Muted"; break; case Status.ERROR_CAS_CARD_INVALID: diagnosticInfo = "Card Invalid"; break; case Status.ERROR_CAS_BLACKOUT: diagnosticInfo = "Blackout"; break; case Status.ERROR_CAS_REBOOTING: diagnosticInfo = "Rebooting"; break; default: diagnosticInfo = "Unknown CAS state exception"; break; Loading Loading
Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -326,8 +326,9 @@ java_library { "framework-protos", "game-driver-protos", "android.hidl.base-V1.0-java", "android.hardware.cas-V1.1-java", "android.hardware.cas-V1.0-java", "android.hardware.cas-V1.1-java", "android.hardware.cas-V1.2-java", "android.hardware.contexthub-V1.0-java", "android.hardware.gnss-V1.0-java", "android.hardware.health-V1.0-java-constants", Loading
api/current.txt +46 −0 Original line number Diff line number Diff line Loading @@ -24789,11 +24789,13 @@ package android.media { public final class MediaCas implements java.lang.AutoCloseable { ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException; ctor public MediaCas(int, @Nullable String, int) throws android.media.MediaCasException.UnsupportedCasException; method public void close(); method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins(); method protected void finalize(); method public static boolean isSystemIdSupported(int); method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException; method @Nullable public android.media.MediaCas.Session openSession(int, int) throws android.media.MediaCasException; method public void processEmm(@NonNull byte[], int, int) throws android.media.MediaCasException; method public void processEmm(@NonNull byte[]) throws android.media.MediaCasException; method public void provision(@NonNull String) throws android.media.MediaCasException; Loading @@ -24801,10 +24803,32 @@ package android.media { method public void sendEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException; method public void setEventListener(@Nullable android.media.MediaCas.EventListener, @Nullable android.os.Handler); method public void setPrivateData(@NonNull byte[]) throws android.media.MediaCasException; field public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = 0; // 0x0 field public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = 1; // 0x1 field public static final int SCRAMBLING_MODE_AES128 = 9; // 0x9 field public static final int SCRAMBLING_MODE_AES_ECB = 10; // 0xa field public static final int SCRAMBLING_MODE_AES_SCTE52 = 11; // 0xb field public static final int SCRAMBLING_MODE_DVB_CISSA_V1 = 6; // 0x6 field public static final int SCRAMBLING_MODE_DVB_CSA1 = 1; // 0x1 field public static final int SCRAMBLING_MODE_DVB_CSA2 = 2; // 0x2 field public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE = 5; // 0x5 field public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL = 4; // 0x4 field public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD = 3; // 0x3 field public static final int SCRAMBLING_MODE_DVB_IDSA = 7; // 0x7 field public static final int SCRAMBLING_MODE_MULTI2 = 8; // 0x8 field public static final int SCRAMBLING_MODE_RESERVED = 0; // 0x0 field public static final int SCRAMBLING_MODE_TDES_ECB = 12; // 0xc field public static final int SCRAMBLING_MODE_TDES_SCTE52 = 13; // 0xd field public static final int SESSION_USAGE_LIVE = 0; // 0x0 field public static final int SESSION_USAGE_PLAYBACK = 1; // 0x1 field public static final int SESSION_USAGE_RECORD = 2; // 0x2 field public static final int SESSION_USAGE_TIMESHIFT = 3; // 0x3 } public static interface MediaCas.EventListener { method public void onEvent(@NonNull android.media.MediaCas, int, int, @Nullable byte[]); method public default void onPluginStatusUpdate(@NonNull android.media.MediaCas, int, int); method public default void onResourceLost(@NonNull android.media.MediaCas); method public default void onSessionEvent(@NonNull android.media.MediaCas, @NonNull android.media.MediaCas.Session, int, int, @Nullable byte[]); } Loading @@ -24815,6 +24839,7 @@ package android.media { public final class MediaCas.Session implements java.lang.AutoCloseable { method public void close(); method @NonNull public byte[] getSessionId(); method public void processEcm(@NonNull byte[], int, int) throws android.media.MediaCasException; method public void processEcm(@NonNull byte[]) throws android.media.MediaCasException; method public void sendSessionEvent(int, int, @Nullable byte[]) throws android.media.MediaCasException; Loading @@ -24827,6 +24852,9 @@ package android.media { public static final class MediaCasException.DeniedByServerException extends android.media.MediaCasException { } public static final class MediaCasException.InsufficientResourceException extends android.media.MediaCasException { } public static final class MediaCasException.NotProvisionedException extends android.media.MediaCasException { } Loading Loading @@ -28813,6 +28841,19 @@ package android.media.tv { field public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1; // 0x1 field public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 4; // 0x4 field public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; // 0x3 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT = 16; // 0x10 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID = 15; // 0xf field public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE = 14; // 0xe field public static final int VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 7; // 0x7 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED = 10; // 0xa field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION = 11; // 0xb field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING = 12; // 0xc field public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD = 13; // 0xd field public static final int VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED = 8; // 0x8 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING = 17; // 0x11 field public static final int VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN = 18; // 0x12 field public static final int VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 6; // 0x6 field public static final int VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 5; // 0x5 field public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; // 0x1 field public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = 0; // 0x0 field public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; // 0x2 Loading @@ -28834,6 +28875,11 @@ package android.media.tv { method @Nullable public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(@NonNull String, @NonNull String); method @Nullable public abstract android.media.tv.TvInputService.Session onCreateSession(String); method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String); field public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100; // 0x64 field public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400; // 0x190 field public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300; // 0x12c field public static final int PRIORITY_HINT_USE_CASE_TYPE_RECORD = 500; // 0x1f4 field public static final int PRIORITY_HINT_USE_CASE_TYPE_SCAN = 200; // 0xc8 field public static final String SERVICE_INTERFACE = "android.media.tv.TvInputService"; field public static final String SERVICE_META_DATA = "android.media.tv.input"; }
media/java/android/media/MediaCas.java +303 −19 Original line number Diff line number Diff line Loading @@ -16,13 +16,15 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.cas.V1_0.HidlCasPluginDescriptor; import android.hardware.cas.V1_0.ICas; import android.hardware.cas.V1_0.IMediaCasService; import android.hardware.cas.V1_1.ICasListener; import android.hardware.cas.V1_2.ICasListener; import android.media.MediaCasException.*; import android.media.tv.TvInputService.PriorityHintUseCaseType; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; Loading @@ -34,6 +36,8 @@ import android.os.RemoteException; import android.util.Log; import android.util.Singleton; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; /** Loading Loading @@ -100,28 +104,185 @@ public final class MediaCas implements AutoCloseable { private static final String TAG = "MediaCas"; private ICas mICas; private android.hardware.cas.V1_1.ICas mICasV11; private android.hardware.cas.V1_2.ICas mICasV12; private EventListener mListener; private HandlerThread mHandlerThread; private EventHandler mEventHandler; private @PriorityHintUseCaseType int mPriorityHint; private String mTvInputServiceSessionId; /** * Scrambling modes used to open cas sessions. * * @hide */ @IntDef(prefix = "SCRAMBLING_MODE_", value = {SCRAMBLING_MODE_RESERVED, SCRAMBLING_MODE_DVB_CSA1, SCRAMBLING_MODE_DVB_CSA2, SCRAMBLING_MODE_DVB_CSA3_STANDARD, SCRAMBLING_MODE_DVB_CSA3_MINIMAL, SCRAMBLING_MODE_DVB_CSA3_ENHANCE, SCRAMBLING_MODE_DVB_CISSA_V1, SCRAMBLING_MODE_DVB_IDSA, SCRAMBLING_MODE_MULTI2, SCRAMBLING_MODE_AES128, SCRAMBLING_MODE_AES_ECB, SCRAMBLING_MODE_AES_SCTE52, SCRAMBLING_MODE_TDES_ECB, SCRAMBLING_MODE_TDES_SCTE52}) @Retention(RetentionPolicy.SOURCE) public @interface ScramblingMode {} /** * DVB (Digital Video Broadcasting) reserved mode. */ public static final int SCRAMBLING_MODE_RESERVED = android.hardware.cas.V1_2.ScramblingMode.RESERVED; /** * DVB (Digital Video Broadcasting) Common Scrambling Algorithm (CSA) 1. */ public static final int SCRAMBLING_MODE_DVB_CSA1 = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA1; /** * DVB CSA 2. */ public static final int SCRAMBLING_MODE_DVB_CSA2 = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA2; /** * DVB CSA 3 in standard mode. */ public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_STANDARD; /** * DVB CSA 3 in minimally enhanced mode. */ public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_MINIMAL; /** * DVB CSA 3 in fully enhanced mode. */ public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE = android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_ENHANCE; /** * DVB Common IPTV Software-oriented Scrambling Algorithm (CISSA) Version 1. */ public static final int SCRAMBLING_MODE_DVB_CISSA_V1 = android.hardware.cas.V1_2.ScramblingMode.DVB_CISSA_V1; /** * ATIS-0800006 IIF Default Scrambling Algorithm (IDSA). */ public static final int SCRAMBLING_MODE_DVB_IDSA = android.hardware.cas.V1_2.ScramblingMode.DVB_IDSA; /** * A symmetric key algorithm. */ public static final int SCRAMBLING_MODE_MULTI2 = android.hardware.cas.V1_2.ScramblingMode.MULTI2; /** * Advanced Encryption System (AES) 128-bit Encryption mode. */ public static final int SCRAMBLING_MODE_AES128 = android.hardware.cas.V1_2.ScramblingMode.AES128; /** * Advanced Encryption System (AES) Electronic Code Book (ECB) mode. */ public static final int SCRAMBLING_MODE_AES_ECB = android.hardware.cas.V1_2.ScramblingMode.AES_ECB; /** * Advanced Encryption System (AES) Society of Cable Telecommunications Engineers (SCTE) 52 * mode. */ public static final int SCRAMBLING_MODE_AES_SCTE52 = android.hardware.cas.V1_2.ScramblingMode.AES_SCTE52; /** * Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode. */ public static final int SCRAMBLING_MODE_TDES_ECB = android.hardware.cas.V1_2.ScramblingMode.TDES_ECB; /** * Triple Data Encryption Algorithm (TDES) Society of Cable Telecommunications Engineers (SCTE) * 52 mode. */ public static final int SCRAMBLING_MODE_TDES_SCTE52 = android.hardware.cas.V1_2.ScramblingMode.TDES_SCTE52; /** * Usages used to open cas sessions. * * @hide */ @IntDef(prefix = "SESSION_USAGE_", value = {SESSION_USAGE_LIVE, SESSION_USAGE_PLAYBACK, SESSION_USAGE_RECORD, SESSION_USAGE_TIMESHIFT}) @Retention(RetentionPolicy.SOURCE) public @interface SessionUsage {} /** * Cas session is used to descramble live streams. */ public static final int SESSION_USAGE_LIVE = android.hardware.cas.V1_2.SessionIntent.LIVE; /** * Cas session is used to descramble recoreded streams. */ public static final int SESSION_USAGE_PLAYBACK = android.hardware.cas.V1_2.SessionIntent.PLAYBACK; /** * Cas session is used to descramble live streams and encrypt local recorded content */ public static final int SESSION_USAGE_RECORD = android.hardware.cas.V1_2.SessionIntent.RECORD; /** * Cas session is used to descramble live streams , encrypt local recorded content and playback * local encrypted content. */ public static final int SESSION_USAGE_TIMESHIFT = android.hardware.cas.V1_2.SessionIntent.TIMESHIFT; /** * Plugin status events sent from cas system. * * @hide */ @IntDef(prefix = "PLUGIN_STATUS_", value = {PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED, PLUGIN_STATUS_SESSION_NUMBER_CHANGED}) @Retention(RetentionPolicy.SOURCE) public @interface PluginStatus {} /** * The event to indicate that the status of CAS system is changed by the removal or insertion of * physical CAS modules. */ public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED = android.hardware.cas.V1_2.StatusEvent.PLUGIN_PHYSICAL_MODULE_CHANGED; /** * The event to indicate that the number of CAS system's session is changed. */ public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED = android.hardware.cas.V1_2.StatusEvent.PLUGIN_SESSION_NUMBER_CHANGED; private static final Singleton<IMediaCasService> sService = new Singleton<IMediaCasService>() { @Override protected IMediaCasService create() { try { Log.d(TAG, "Tried to get cas@1.1 service"); Log.d(TAG, "Trying to get cas@1.2 service"); android.hardware.cas.V1_2.IMediaCasService serviceV12 = android.hardware.cas.V1_2.IMediaCasService.getService(true /*wait*/); if (serviceV12 != null) { return serviceV12; } } catch (Exception eV1_2) { Log.d(TAG, "Failed to get cas@1.2 service"); } try { Log.d(TAG, "Trying to get cas@1.1 service"); android.hardware.cas.V1_1.IMediaCasService serviceV11 = android.hardware.cas.V1_1.IMediaCasService.getService(true /*wait*/); if (serviceV11 != null) { return serviceV11; } } catch (Exception eV1_1) { Log.d(TAG, "Failed to get cas@1.1 service"); } try { Log.d(TAG, "Tried to get cas@1.0 service"); Log.d(TAG, "Trying to get cas@1.0 service"); return IMediaCasService.getService(true /*wait*/); } catch (Exception eV1_0) { Log.d(TAG, "Failed to get cas@1.0 service"); } } return null; } }; Loading @@ -139,6 +300,7 @@ public final class MediaCas implements AutoCloseable { private void cleanupAndRethrowIllegalState() { mICas = null; mICasV11 = null; mICasV12 = null; throw new IllegalStateException(); } Loading @@ -146,6 +308,8 @@ public final class MediaCas implements AutoCloseable { private static final int MSG_CAS_EVENT = 0; private static final int MSG_CAS_SESSION_EVENT = 1; private static final int MSG_CAS_STATUS_EVENT = 2; private static final int MSG_CAS_RESOURCE_LOST = 3; private static final String SESSION_KEY = "sessionId"; private static final String DATA_KEY = "data"; Loading @@ -164,6 +328,10 @@ public final class MediaCas implements AutoCloseable { mListener.onSessionEvent(MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, bundle.getByteArray(DATA_KEY)); } else if (msg.what == MSG_CAS_STATUS_EVENT) { mListener.onPluginStatusUpdate(MediaCas.this, msg.arg1, msg.arg2); } else if (msg.what == MSG_CAS_RESOURCE_LOST) { mListener.onResourceLost(MediaCas.this); } } } Loading @@ -189,6 +357,12 @@ public final class MediaCas implements AutoCloseable { msg.setData(bundle); mEventHandler.sendMessage(msg); } @Override public void onStatusUpdate(byte status, int arg) throws RemoteException { mEventHandler.sendMessage(mEventHandler.obtainMessage( EventHandler.MSG_CAS_STATUS_EVENT, status, arg)); } }; /** * Describe a CAS plugin with its CA_system_ID and string name. Loading Loading @@ -257,7 +431,7 @@ public final class MediaCas implements AutoCloseable { final ArrayList<Byte> mSessionId; Session(@NonNull ArrayList<Byte> sessionId) { mSessionId = sessionId; mSessionId = new ArrayList<Byte>(sessionId); } /** Loading Loading @@ -363,6 +537,19 @@ public final class MediaCas implements AutoCloseable { } } /** * Get Session Id. * * @return session Id of the session. * * @throws IllegalStateException if the MediaCas instance is not valid. */ @NonNull public byte[] getSessionId() { validateInternalStates(); return toBytes(mSessionId); } /** * Close the session. * Loading Loading @@ -445,6 +632,9 @@ public final class MediaCas implements AutoCloseable { public MediaCas(int CA_system_id) throws UnsupportedCasException { try { IMediaCasService service = getService(); android.hardware.cas.V1_2.IMediaCasService serviceV12 = android.hardware.cas.V1_2.IMediaCasService.castFrom(service); if (serviceV12 == null) { android.hardware.cas.V1_1.IMediaCasService serviceV11 = android.hardware.cas.V1_1.IMediaCasService.castFrom(service); if (serviceV11 == null) { Loading @@ -454,6 +644,12 @@ public final class MediaCas implements AutoCloseable { Log.d(TAG, "Used cas@1.1 interface to create plugin"); mICas = mICasV11 = serviceV11.createPluginExt(CA_system_id, mBinder); } } else { Log.d(TAG, "Used cas@1.2 interface to create plugin"); mICas = mICasV11 = mICasV12 = android.hardware.cas.V1_2.ICas .castFrom(serviceV12.createPluginExt(CA_system_id, mBinder)); } } catch(Exception e) { Log.e(TAG, "Failed to create plugin: " + e); mICas = null; Loading @@ -465,6 +661,24 @@ public final class MediaCas implements AutoCloseable { } } /** * Instantiate a CA system of the specified system id. * * @param casSystemId The system id of the CA system. * @param tvInputServiceSessionId The Id of the session opened in TV Input Service (TIS) * {@link android.media.tv.TvInputService#onCreateSession(String, String)} * @param priorityHint priority hint from the use case type for new created CAS system. * * @throws UnsupportedCasException if the device does not support the * specified CA system. */ public MediaCas(int casSystemId, @Nullable String tvInputServiceSessionId, @PriorityHintUseCaseType int priorityHint) throws UnsupportedCasException { this(casSystemId); mPriorityHint = priorityHint; mTvInputServiceSessionId = tvInputServiceSessionId; } IHwBinder getBinder() { validateInternalStates(); Loading @@ -476,6 +690,7 @@ public final class MediaCas implements AutoCloseable { * to receives scheme-specific notifications from a MediaCas instance. */ public interface EventListener { /** * Notify the listener of a scheme-specific event from the CA system. * Loading @@ -501,6 +716,27 @@ public final class MediaCas implements AutoCloseable { int event, int arg, @Nullable byte[] data) { Log.d(TAG, "Received MediaCas Session event"); } /** * Notify the listener that the cas plugin status is updated. * * @param mediaCas the MediaCas object to receive this event. * @param status the plugin status which is updated. * @param arg an integer whose meaning is specific to the status to be updated. */ default void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status, int arg) { Log.d(TAG, "Received MediaCas Plugin Status event"); } /** * Notify the listener that the session resources was lost. * * @param mediaCas the MediaCas object to receive this event. */ default void onResourceLost(@NonNull MediaCas mediaCas) { Log.d(TAG, "Received MediaCas Resource Reclaim event"); } } /** Loading Loading @@ -563,6 +799,20 @@ public final class MediaCas implements AutoCloseable { mSession = createFromSessionId(sessionId); } } private class OpenSession_1_2_Callback implements android.hardware.cas.V1_2.ICas.openSession_1_2Callback { public Session mSession; public int mStatus; @Override public void onValues(int status, ArrayList<Byte> sessionId) { mStatus = status; mSession = createFromSessionId(sessionId); } } /** * Open a session to descramble one or more streams scrambled by the * conditional access system. Loading @@ -587,6 +837,40 @@ public final class MediaCas implements AutoCloseable { return null; } /** * Open a session with usage and scrambling information, so that descrambler can be configured * to descramble one or more streams scrambled by the conditional access system. * * @param sessionUsage used for the created session. * @param scramblingMode used for the created session. * * @return session the newly opened session. * * @throws IllegalStateException if the MediaCas instance is not valid. * @throws MediaCasException for CAS-specific errors. * @throws MediaCasStateException for CAS-specific state exceptions. */ @Nullable public Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode) throws MediaCasException { validateInternalStates(); if (mICasV12 == null) { Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface"); throw new UnsupportedCasException("Open Session with scrambling mode is not supported"); } try { OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback(); mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb); MediaCasException.throwExceptionIfNeeded(cb.mStatus); return cb.mSession; } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } return null; } /** * Send a received EMM packet to the CA system. * Loading
media/java/android/media/MediaCasException.java +12 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ package android.media; import android.hardware.cas.V1_0.Status; import android.hardware.cas.V1_2.Status; /** * Base class for MediaCas exceptions Loading Loading @@ -85,4 +85,15 @@ public class MediaCasException extends Exception { super(detailMessage); } } /** * Exception thrown when an operation on a MediaCas object is attempted * and hardware resources are not sufficient to allocate, due to client's lower priority. */ public static final class InsufficientResourceException extends MediaCasException { /** @hide */ public InsufficientResourceException(String detailMessage) { super(detailMessage); } } }
media/java/android/media/MediaCasStateException.java +55 −35 Original line number Diff line number Diff line Loading @@ -18,8 +18,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.cas.V1_0.Status; import android.hardware.cas.V1_2.Status; /** * Base class for MediaCas runtime exceptions Loading Loading @@ -78,6 +77,27 @@ public class MediaCasStateException extends IllegalStateException { case Status.ERROR_CAS_DECRYPT: diagnosticInfo = "Decrypt error"; break; case Status.ERROR_CAS_NEED_ACTIVATION: diagnosticInfo = "Need Activation"; break; case Status.ERROR_CAS_NEED_PAIRING: diagnosticInfo = "Need Pairing"; break; case Status.ERROR_CAS_NO_CARD: diagnosticInfo = "No Card"; break; case Status.ERROR_CAS_CARD_MUTE: diagnosticInfo = "Card Muted"; break; case Status.ERROR_CAS_CARD_INVALID: diagnosticInfo = "Card Invalid"; break; case Status.ERROR_CAS_BLACKOUT: diagnosticInfo = "Blackout"; break; case Status.ERROR_CAS_REBOOTING: diagnosticInfo = "Rebooting"; break; default: diagnosticInfo = "Unknown CAS state exception"; break; Loading