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

Commit 0129cd7d authored by Henry Fang's avatar Henry Fang Committed by Android (Google) Code Review
Browse files

Merge "Framework support cas@1.2"

parents 77a699ba 43cab92a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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",
+46 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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[]);
  }
@@ -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;
@@ -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 {
  }
@@ -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
@@ -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";
  }
+303 −19
Original line number Diff line number Diff line
@@ -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;
@@ -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;

/**
@@ -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;
        }
    };
@@ -139,6 +300,7 @@ public final class MediaCas implements AutoCloseable {
    private void cleanupAndRethrowIllegalState() {
        mICas = null;
        mICasV11 = null;
        mICasV12 = null;
        throw new IllegalStateException();
    }

@@ -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";

@@ -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);
            }
        }
    }
@@ -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.
@@ -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);
        }

        /**
@@ -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.
         *
@@ -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) {
@@ -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;
@@ -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();

@@ -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.
         *
@@ -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");
        }
    }

    /**
@@ -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.
@@ -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.
     *
+12 −1
Original line number Diff line number Diff line
@@ -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
@@ -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);
        }
    }
}
+55 −35
Original line number Diff line number Diff line
@@ -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
@@ -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