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

Commit fd89a95f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic 'api-review' into oc-dev

* changes:
  MediaCas: combine openSession methods
  MediaCas: address comments for API reviews
parents 96907e65 625e1804
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -21810,24 +21810,19 @@ package android.media {
    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
  }
  public final class MediaCas {
  public final class MediaCas implements java.lang.AutoCloseable {
    ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
    method public void closeSession(byte[]);
    method public void close();
    method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
    method public static boolean isSystemIdSupported(int);
    method public byte[] openSession(int) throws android.media.MediaCasException;
    method public byte[] openSession(int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
    method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
    method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
    method public void processEmm(byte[]) throws android.media.MediaCasException;
    method public void provision(java.lang.String) throws android.media.MediaCasException;
    method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
    method public void release();
    method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
    method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
    method public void setPrivateData(byte[]) throws android.media.MediaCasException;
    method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
  }
  public static abstract interface MediaCas.EventListener {
@@ -21839,6 +21834,13 @@ package android.media {
    method public int getSystemId();
  }
  public final class MediaCas.Session implements java.lang.AutoCloseable {
    method public void close();
    method public void processEcm(byte[], int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[]) throws android.media.MediaCasException;
    method public void setPrivateData(byte[]) throws android.media.MediaCasException;
  }
  public class MediaCasException extends java.lang.Exception {
  }
@@ -22282,12 +22284,12 @@ package android.media {
    method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
  }
  public final class MediaDescrambler {
  public final class MediaDescrambler implements java.lang.AutoCloseable {
    ctor public MediaDescrambler(int) throws android.media.MediaCasException.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 void close();
    method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
    method public final boolean requiresSecureDecoderComponent(java.lang.String);
    method public final void setMediaCasSession(byte[]);
    method public final void setMediaCasSession(android.media.MediaCas.Session);
  }
  public class MediaDescription implements android.os.Parcelable {
@@ -22425,6 +22427,7 @@ package android.media {
    ctor public MediaExtractor();
    method public boolean advance();
    method public long getCachedDuration();
    method public android.media.MediaExtractor.CasInfo getCasInfo(int);
    method public android.media.DrmInitData getDrmInitData();
    method public android.media.MediaMetricsSet getMetrics();
    method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
@@ -22456,6 +22459,11 @@ package android.media {
    field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
  }
  public static final class MediaExtractor.CasInfo {
    method public android.media.MediaCas.Session getSession();
    method public int getSystemId();
  }
  public final class MediaFormat {
    ctor public MediaFormat();
    method public final boolean containsKey(java.lang.String);
+20 −12
Original line number Diff line number Diff line
@@ -23639,24 +23639,19 @@ package android.media {
    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
  }
  public final class MediaCas {
  public final class MediaCas implements java.lang.AutoCloseable {
    ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
    method public void closeSession(byte[]);
    method public void close();
    method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
    method public static boolean isSystemIdSupported(int);
    method public byte[] openSession(int) throws android.media.MediaCasException;
    method public byte[] openSession(int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
    method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
    method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
    method public void processEmm(byte[]) throws android.media.MediaCasException;
    method public void provision(java.lang.String) throws android.media.MediaCasException;
    method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
    method public void release();
    method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
    method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
    method public void setPrivateData(byte[]) throws android.media.MediaCasException;
    method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
  }
  public static abstract interface MediaCas.EventListener {
@@ -23668,6 +23663,13 @@ package android.media {
    method public int getSystemId();
  }
  public final class MediaCas.Session implements java.lang.AutoCloseable {
    method public void close();
    method public void processEcm(byte[], int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[]) throws android.media.MediaCasException;
    method public void setPrivateData(byte[]) throws android.media.MediaCasException;
  }
  public class MediaCasException extends java.lang.Exception {
  }
@@ -24111,12 +24113,12 @@ package android.media {
    method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
  }
  public final class MediaDescrambler {
  public final class MediaDescrambler implements java.lang.AutoCloseable {
    ctor public MediaDescrambler(int) throws android.media.MediaCasException.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 void close();
    method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
    method public final boolean requiresSecureDecoderComponent(java.lang.String);
    method public final void setMediaCasSession(byte[]);
    method public final void setMediaCasSession(android.media.MediaCas.Session);
  }
  public class MediaDescription implements android.os.Parcelable {
@@ -24254,6 +24256,7 @@ package android.media {
    ctor public MediaExtractor();
    method public boolean advance();
    method public long getCachedDuration();
    method public android.media.MediaExtractor.CasInfo getCasInfo(int);
    method public android.media.DrmInitData getDrmInitData();
    method public android.media.MediaMetricsSet getMetrics();
    method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
@@ -24285,6 +24288,11 @@ package android.media {
    field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
  }
  public static final class MediaExtractor.CasInfo {
    method public android.media.MediaCas.Session getSession();
    method public int getSystemId();
  }
  public final class MediaFormat {
    ctor public MediaFormat();
    method public final boolean containsKey(java.lang.String);
+20 −12
Original line number Diff line number Diff line
@@ -21925,24 +21925,19 @@ package android.media {
    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
  }
  public final class MediaCas {
  public final class MediaCas implements java.lang.AutoCloseable {
    ctor public MediaCas(int) throws android.media.MediaCasException.UnsupportedCasException;
    method public void closeSession(byte[]);
    method public void close();
    method public static android.media.MediaCas.PluginDescriptor[] enumeratePlugins();
    method public static boolean isSystemIdSupported(int);
    method public byte[] openSession(int) throws android.media.MediaCasException;
    method public byte[] openSession(int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[], byte[], int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[], byte[]) throws android.media.MediaCasException;
    method public android.media.MediaCas.Session openSession() throws android.media.MediaCasException;
    method public void processEmm(byte[], int, int) throws android.media.MediaCasException;
    method public void processEmm(byte[]) throws android.media.MediaCasException;
    method public void provision(java.lang.String) throws android.media.MediaCasException;
    method public void refreshEntitlements(int, byte[]) throws android.media.MediaCasException;
    method public void release();
    method public void sendEvent(int, int, byte[]) throws android.media.MediaCasException;
    method public void setEventListener(android.media.MediaCas.EventListener, android.os.Handler);
    method public void setPrivateData(byte[]) throws android.media.MediaCasException;
    method public void setSessionPrivateData(byte[], byte[]) throws android.media.MediaCasException;
  }
  public static abstract interface MediaCas.EventListener {
@@ -21954,6 +21949,13 @@ package android.media {
    method public int getSystemId();
  }
  public final class MediaCas.Session implements java.lang.AutoCloseable {
    method public void close();
    method public void processEcm(byte[], int, int) throws android.media.MediaCasException;
    method public void processEcm(byte[]) throws android.media.MediaCasException;
    method public void setPrivateData(byte[]) throws android.media.MediaCasException;
  }
  public class MediaCasException extends java.lang.Exception {
  }
@@ -22397,12 +22399,12 @@ package android.media {
    method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
  }
  public final class MediaDescrambler {
  public final class MediaDescrambler implements java.lang.AutoCloseable {
    ctor public MediaDescrambler(int) throws android.media.MediaCasException.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 void close();
    method public final int descramble(java.nio.ByteBuffer, java.nio.ByteBuffer, android.media.MediaCodec.CryptoInfo);
    method public final boolean requiresSecureDecoderComponent(java.lang.String);
    method public final void setMediaCasSession(byte[]);
    method public final void setMediaCasSession(android.media.MediaCas.Session);
  }
  public class MediaDescription implements android.os.Parcelable {
@@ -22540,6 +22542,7 @@ package android.media {
    ctor public MediaExtractor();
    method public boolean advance();
    method public long getCachedDuration();
    method public android.media.MediaExtractor.CasInfo getCasInfo(int);
    method public android.media.DrmInitData getDrmInitData();
    method public android.media.MediaMetricsSet getMetrics();
    method public java.util.Map<java.util.UUID, byte[]> getPsshInfo();
@@ -22571,6 +22574,11 @@ package android.media {
    field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
  }
  public static final class MediaExtractor.CasInfo {
    method public android.media.MediaCas.Session getSession();
    method public int getSystemId();
  }
  public final class MediaFormat {
    ctor public MediaFormat();
    method public final boolean containsKey(java.lang.String);
+118 −131
Original line number Diff line number Diff line
@@ -51,12 +51,13 @@ import android.util.Singleton;
 * management messages) can be distributed out-of-band, or in-band with the stream.
 * <p>
 * To descramble elementary streams, the app first calls {@link #openSession} to
 * generate a sessionId that will uniquely identify a session. A session provides
 * a context for subsequent key updates and descrambling activities. The ECMs
 * (Entitlement control messages) are sent to the session via method {@link #processEcm}.
 * generate a {@link Session} object that will uniquely identify a session. A session
 * provides a context for subsequent key updates and descrambling activities. The ECMs
 * (Entitlement control messages) are sent to the session via method
 * {@link Session#processEcm}.
 * <p>
 * The app next constructs a MediaDescrambler object, and initializes it with the
 * sessionId using {@link MediaDescrambler#setMediaCasSession}. This ties the
 * session using {@link MediaDescrambler#setMediaCasSession}. This ties the
 * descrambler to the session, and the descrambler can then be used to descramble
 * content secured with the session's key, either during extraction, or during decoding
 * with {@link android.media.MediaCodec}.
@@ -79,19 +80,20 @@ import android.util.Singleton;
 * If the app uses {@link MediaExtractor}, it can delegate the CAS session
 * management to MediaExtractor by calling {@link MediaExtractor#setMediaCas}.
 * MediaExtractor will take over and call {@link #openSession}, {@link #processEmm}
 * and/or {@link #processEcm}, etc.. if necessary.
 * and/or {@link Session#processEcm}, etc.. if necessary.
 * <p>
 * When using {@link MediaExtractor}, the app would still need a MediaDescrambler
 * to use with {@link MediaCodec} if the licensing requires a secure decoder. The
 * sessionId of the descrambler can be retrieved by {@link MediaExtractor#getDrmInitData}
 * and used to initialize a MediaDescrambler object for MediaCodec.
 * session associated with the descrambler of a track can be retrieved by calling
 * {@link MediaExtractor#getCasInfo}, and used to initialize a MediaDescrambler
 * object for MediaCodec.
 * <p>
 * <h3>Listeners</h3>
 * <p>The app may register a listener to receive events from the CA system using
 * method {@link #setEventListener}. The exact format of the event is scheme-specific
 * and is not specified by this API.
 */
public final class MediaCas {
public final class MediaCas implements AutoCloseable {
    private static final String TAG = "MediaCas";
    private final ParcelableCasData mCasData = new ParcelableCasData();
    private ICas mICas;
@@ -228,6 +230,106 @@ public final class MediaCas {
        }
    }

    /**
     * Class for an open session with the CA system.
     */
    public final class Session implements AutoCloseable {
        final byte[] mSessionId;

        Session(@NonNull byte[] sessionId) {
            mSessionId = sessionId;
        }

        /**
         * Set the private data for a session.
         *
         * @param data byte array of the private data.
         *
         * @throws IllegalStateException if the MediaCas instance is not valid.
         * @throws MediaCasException for CAS-specific errors.
         * @throws MediaCasStateException for CAS-specific state exceptions.
         */
        public void setPrivateData(@NonNull byte[] data)
                throws MediaCasException {
            validateInternalStates();

            try {
                mICas.setSessionPrivateData(mSessionId, data);
            } catch (ServiceSpecificException e) {
                MediaCasException.throwExceptions(e);
            } catch (RemoteException e) {
                cleanupAndRethrowIllegalState();
            }
        }


        /**
         * Send a received ECM packet to the specified session of the CA system.
         *
         * @param data byte array of the ECM data.
         * @param offset position within data where the ECM data begins.
         * @param length length of the data (starting from offset).
         *
         * @throws IllegalStateException if the MediaCas instance is not valid.
         * @throws MediaCasException for CAS-specific errors.
         * @throws MediaCasStateException for CAS-specific state exceptions.
         */
        public void processEcm(@NonNull byte[] data, int offset, int length)
                throws MediaCasException {
            validateInternalStates();

            try {
                mCasData.set(data, offset, length);
                mICas.processEcm(mSessionId, mCasData);
            } catch (ServiceSpecificException e) {
                MediaCasException.throwExceptions(e);
            } catch (RemoteException e) {
                cleanupAndRethrowIllegalState();
            }
        }

        /**
         * Send a received ECM packet to the specified session of the CA system.
         * This is similar to {@link Session#processEcm(byte[], int, int)}
         * except that the entire byte array is sent.
         *
         * @param data byte array of the ECM data.
         *
         * @throws IllegalStateException if the MediaCas instance is not valid.
         * @throws MediaCasException for CAS-specific errors.
         * @throws MediaCasStateException for CAS-specific state exceptions.
         */
        public void processEcm(@NonNull byte[] data) throws MediaCasException {
            processEcm(data, 0, data.length);
        }

        /**
         * Close the session.
         *
         * @throws IllegalStateException if the MediaCas instance is not valid.
         * @throws MediaCasStateException for CAS-specific state exceptions.
         */
        @Override
        public void close() {
            validateInternalStates();

            try {
                mICas.closeSession(mSessionId);
            } catch (ServiceSpecificException e) {
                MediaCasStateException.throwExceptions(e);
            } catch (RemoteException e) {
                cleanupAndRethrowIllegalState();
            }
        }
    }

    Session createFromSessionId(byte[] sessionId) {
        if (sessionId == null || sessionId.length == 0) {
            return null;
        }
        return new Session(sessionId);
    }

    /**
     * Class for parceling CAS plugin descriptors over IMediaCasService binder.
     */
@@ -404,21 +506,20 @@ public final class MediaCas {
    }

    /**
     * Open a session for the specified program.
     *
     * @param programNumber program_number of the program (as in ISO/IEC13818-1).
     * Open a session to descramble one or more streams scrambled by the
     * conditional access system.
     *
     * @return session id of the newly opened 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.
     */
    public byte[] openSession(int programNumber) throws MediaCasException {
    public Session openSession() throws MediaCasException {
        validateInternalStates();

        try {
            return mICas.openSession(programNumber);
            return createFromSessionId(mICas.openSession());
        } catch (ServiceSpecificException e) {
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
@@ -427,118 +528,6 @@ public final class MediaCas {
        return null;
    }

    /**
     * Open a session for the specified stream.
     *
     * @param programNumber program_number of the stream (as in ISO/IEC13818-1).
     * @param elementaryPID elementary_PID of the stream (as in ISO/IEC13818-1).
     *
     * @return session id of 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.
     */
    public byte[] openSession(int programNumber, int elementaryPID)
            throws MediaCasException {
        validateInternalStates();

        try {
            return mICas.openSessionForStream(programNumber, elementaryPID);
        } catch (ServiceSpecificException e) {
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
        }
        return null;
    }

    /**
     * Close the specified session.
     *
     * @param sessionId the session to be closed.
     *
     * @throws IllegalStateException if the MediaCas instance is not valid.
     * @throws MediaCasStateException for CAS-specific state exceptions.
     */
    public void closeSession(@NonNull byte[] sessionId) {
        validateInternalStates();

        try {
            mICas.closeSession(sessionId);
        } catch (ServiceSpecificException e) {
            MediaCasStateException.throwExceptions(e);
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
        }
    }

    /**
     * Set the private data for a session.
     *
     * @param sessionId the session for which the private data is intended.
     * @param data byte array of the private data.
     *
     * @throws IllegalStateException if the MediaCas instance is not valid.
     * @throws MediaCasException for CAS-specific errors.
     * @throws MediaCasStateException for CAS-specific state exceptions.
     */
    public void setSessionPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data)
            throws MediaCasException {
        validateInternalStates();

        try {
            mICas.setSessionPrivateData(sessionId, data);
        } catch (ServiceSpecificException e) {
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
        }
    }

    /**
     * Send a received ECM packet to the specified session of the CA system.
     *
     * @param sessionId the session for which the ECM is intended.
     * @param data byte array of the ECM data.
     * @param offset position within data where the ECM data begins.
     * @param length length of the data (starting from offset).
     *
     * @throws IllegalStateException if the MediaCas instance is not valid.
     * @throws MediaCasException for CAS-specific errors.
     * @throws MediaCasStateException for CAS-specific state exceptions.
     */
    public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data,
            int offset, int length) throws MediaCasException {
        validateInternalStates();

        try {
            mCasData.set(data, offset, length);
            mICas.processEcm(sessionId, mCasData);
        } catch (ServiceSpecificException e) {
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
        }
    }

    /**
     * Send a received ECM packet to the specified session of the CA system.
     * This is similar to {@link #processEcm(byte[], byte[], int, int)}
     * except that the entire byte array is sent.
     *
     * @param sessionId the session for which the ECM is intended.
     * @param data byte array of the ECM data.
     *
     * @throws IllegalStateException if the MediaCas instance is not valid.
     * @throws MediaCasException for CAS-specific errors.
     * @throws MediaCasStateException for CAS-specific state exceptions.
     */
    public void processEcm(@NonNull byte[] sessionId, @NonNull byte[] data)
            throws MediaCasException {
        processEcm(sessionId, data, 0, data.length);
    }

    /**
     * Send a received EMM packet to the CA system.
     *
@@ -650,10 +639,8 @@ public final class MediaCas {
        }
    }

    /**
     * Release the MediaCas instance.
     */
    public void release() {
    @Override
    public void close() {
        if (mICas != null) {
            try {
                mICas.release();
@@ -666,6 +653,6 @@ public final class MediaCas {

    @Override
    protected void finalize() {
        release();
        close();
    }
}
 No newline at end of file
+16 −14

File changed.

Preview size limit exceeded, changes collapsed.

Loading