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

Commit 2659c2f1 authored by Chong Zhang's avatar Chong Zhang
Browse files

cas: convert MediaCas to HIDL

- Replace AIDL interfaces with corresponding HIDL ones.

bug: 22804304
Change-Id: I8c552ce6fc3766715cd1bc0ea05c0988d56f590e
parent b425e002
Loading
Loading
Loading
Loading
+2 −4
Original line number Original line Diff line number Diff line
@@ -437,10 +437,6 @@ LOCAL_SRC_FILES += \
	location/java/android/location/INetInitiatedListener.aidl \
	location/java/android/location/INetInitiatedListener.aidl \
	location/java/com/android/internal/location/ILocationProvider.aidl \
	location/java/com/android/internal/location/ILocationProvider.aidl \
	media/java/android/media/IAudioService.aidl \
	media/java/android/media/IAudioService.aidl \
	../av/drm/libmediadrm/aidl/android/media/ICas.aidl \
	../av/drm/libmediadrm/aidl/android/media/ICasListener.aidl \
	../av/drm/libmediadrm/aidl/android/media/IDescrambler.aidl \
	../av/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl \
	media/java/android/media/IAudioFocusDispatcher.aidl \
	media/java/android/media/IAudioFocusDispatcher.aidl \
	media/java/android/media/IAudioRoutesObserver.aidl \
	media/java/android/media/IAudioRoutesObserver.aidl \
	media/java/android/media/IMediaHTTPConnection.aidl \
	media/java/android/media/IMediaHTTPConnection.aidl \
@@ -613,6 +609,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
    android.hardware.vibrator-V1.1-java-constants        \
    android.hardware.vibrator-V1.1-java-constants        \
    android.hardware.wifi-V1.0-java-constants            \
    android.hardware.wifi-V1.0-java-constants            \


include hardware/interfaces/cas/1.0/CasHal.mk

# Loaded with System.loadLibrary by android.view.textclassifier
# Loaded with System.loadLibrary by android.view.textclassifier
LOCAL_REQUIRED_MODULES += libtextclassifier
LOCAL_REQUIRED_MODULES += libtextclassifier


+78 −130
Original line number Original line Diff line number Diff line
@@ -18,21 +18,20 @@ package android.media;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.hardware.cas.V1_0.*;
import android.media.MediaCasException.*;
import android.media.MediaCasException.*;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IHwBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.util.Log;
import android.util.Log;
import android.util.Singleton;
import android.util.Singleton;


import java.util.ArrayList;

/**
/**
 * MediaCas can be used to obtain keys for descrambling protected media streams, in
 * MediaCas can be used to obtain keys for descrambling protected media streams, in
 * conjunction with {@link android.media.MediaDescrambler}. The MediaCas APIs are
 * conjunction with {@link android.media.MediaDescrambler}. The MediaCas APIs are
@@ -95,7 +94,6 @@ import android.util.Singleton;
 */
 */
public final class MediaCas implements AutoCloseable {
public final class MediaCas implements AutoCloseable {
    private static final String TAG = "MediaCas";
    private static final String TAG = "MediaCas";
    private final ParcelableCasData mCasData = new ParcelableCasData();
    private ICas mICas;
    private ICas mICas;
    private EventListener mListener;
    private EventListener mListener;
    private HandlerThread mHandlerThread;
    private HandlerThread mHandlerThread;
@@ -105,8 +103,10 @@ public final class MediaCas implements AutoCloseable {
            new Singleton<IMediaCasService>() {
            new Singleton<IMediaCasService>() {
        @Override
        @Override
        protected IMediaCasService create() {
        protected IMediaCasService create() {
            return IMediaCasService.Stub.asInterface(
            try {
                    ServiceManager.getService("media.cas"));
                return IMediaCasService.getService();
            } catch (RemoteException e) {}
            return null;
        }
        }
    };
    };


@@ -136,65 +136,21 @@ public final class MediaCas implements AutoCloseable {
        @Override
        @Override
        public void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
            if (msg.what == MSG_CAS_EVENT) {
            if (msg.what == MSG_CAS_EVENT) {
                mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2, (byte[]) msg.obj);
                mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2,
                        toBytes((ArrayList<Byte>) msg.obj));
            }
            }
        }
        }
    }
    }


    private final ICasListener.Stub mBinder = new ICasListener.Stub() {
    private final ICasListener.Stub mBinder = new ICasListener.Stub() {
        @Override
        @Override
        public void onEvent(int event, int arg, @Nullable byte[] data)
        public void onEvent(int event, int arg, @Nullable ArrayList<Byte> data)
                throws RemoteException {
                throws RemoteException {
            mEventHandler.sendMessage(mEventHandler.obtainMessage(
            mEventHandler.sendMessage(mEventHandler.obtainMessage(
                    EventHandler.MSG_CAS_EVENT, event, arg, data));
                    EventHandler.MSG_CAS_EVENT, event, arg, data));
        }
        }
    };
    };


    /**
     * Class for parceling byte array data over ICas binder.
     */
    static class ParcelableCasData implements Parcelable {
        private byte[] mData;
        private int mOffset;
        private int mLength;

        ParcelableCasData() {
            mData = null;
            mOffset = mLength = 0;
        }

        private ParcelableCasData(Parcel in) {
            this();
        }

        void set(@NonNull byte[] data, int offset, int length) {
            mData = data;
            mOffset = offset;
            mLength = length;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeByteArray(mData, mOffset, mLength);
        }

        public static final Parcelable.Creator<ParcelableCasData> CREATOR
                = new Parcelable.Creator<ParcelableCasData>() {
            public ParcelableCasData createFromParcel(Parcel in) {
                return new ParcelableCasData(in);
            }

            public ParcelableCasData[] newArray(int size) {
                return new ParcelableCasData[size];
            }
        };
    }

    /**
    /**
     * Describe a CAS plugin with its CA_system_ID and string name.
     * Describe a CAS plugin with its CA_system_ID and string name.
     *
     *
@@ -210,9 +166,9 @@ public final class MediaCas implements AutoCloseable {
            mName = null;
            mName = null;
        }
        }


        PluginDescriptor(int CA_system_id, String name) {
        PluginDescriptor(@NonNull HidlCasPluginDescriptor descriptor) {
            mCASystemId = CA_system_id;
            mCASystemId = descriptor.caSystemId;
            mName = name;
            mName = descriptor.name;
        }
        }


        public int getSystemId() {
        public int getSystemId() {
@@ -230,13 +186,38 @@ public final class MediaCas implements AutoCloseable {
        }
        }
    }
    }


    private ArrayList<Byte> toByteArray(@NonNull byte[] data, int offset, int length) {
        ArrayList<Byte> byteArray = new ArrayList<Byte>(length);
        for (int i = 0; i < length; i++) {
            byteArray.add(Byte.valueOf(data[offset + i]));
        }
        return byteArray;
    }

    private ArrayList<Byte> toByteArray(@Nullable byte[] data) {
        if (data == null) {
            return new ArrayList<Byte>();
        }
        return toByteArray(data, 0, data.length);
    }

    private byte[] toBytes(@NonNull ArrayList<Byte> byteArray) {
        byte[] data = null;
        if (byteArray != null) {
            data = new byte[byteArray.size()];
            for (int i = 0; i < data.length; i++) {
                data[i] = byteArray.get(i);
            }
        }
        return data;
    }
    /**
    /**
     * Class for an open session with the CA system.
     * Class for an open session with the CA system.
     */
     */
    public final class Session implements AutoCloseable {
    public final class Session implements AutoCloseable {
        final byte[] mSessionId;
        final ArrayList<Byte> mSessionId;


        Session(@NonNull byte[] sessionId) {
        Session(@NonNull ArrayList<Byte> sessionId) {
            mSessionId = sessionId;
            mSessionId = sessionId;
        }
        }


@@ -254,9 +235,8 @@ public final class MediaCas implements AutoCloseable {
            validateInternalStates();
            validateInternalStates();


            try {
            try {
                mICas.setSessionPrivateData(mSessionId, data);
                MediaCasException.throwExceptionIfNeeded(
            } catch (ServiceSpecificException e) {
                        mICas.setSessionPrivateData(mSessionId, toByteArray(data, 0, data.length)));
                MediaCasException.throwExceptions(e);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
                cleanupAndRethrowIllegalState();
                cleanupAndRethrowIllegalState();
            }
            }
@@ -279,10 +259,8 @@ public final class MediaCas implements AutoCloseable {
            validateInternalStates();
            validateInternalStates();


            try {
            try {
                mCasData.set(data, offset, length);
                MediaCasException.throwExceptionIfNeeded(
                mICas.processEcm(mSessionId, mCasData);
                        mICas.processEcm(mSessionId, toByteArray(data, offset, length)));
            } catch (ServiceSpecificException e) {
                MediaCasException.throwExceptions(e);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
                cleanupAndRethrowIllegalState();
                cleanupAndRethrowIllegalState();
            }
            }
@@ -314,56 +292,21 @@ public final class MediaCas implements AutoCloseable {
            validateInternalStates();
            validateInternalStates();


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


    Session createFromSessionId(byte[] sessionId) {
    Session createFromSessionId(@NonNull ArrayList<Byte> sessionId) {
        if (sessionId == null || sessionId.length == 0) {
        if (sessionId == null || sessionId.size() == 0) {
            return null;
            return null;
        }
        }
        return new Session(sessionId);
        return new Session(sessionId);
    }
    }


    /**
     * Class for parceling CAS plugin descriptors over IMediaCasService binder.
     */
    static class ParcelableCasPluginDescriptor
        extends PluginDescriptor implements Parcelable {

        private ParcelableCasPluginDescriptor(int CA_system_id, String name) {
            super(CA_system_id, name);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            Log.w(TAG, "ParcelableCasPluginDescriptor.writeToParcel shouldn't be called!");
        }

        public static final Parcelable.Creator<ParcelableCasPluginDescriptor> CREATOR
                = new Parcelable.Creator<ParcelableCasPluginDescriptor>() {
            public ParcelableCasPluginDescriptor createFromParcel(Parcel in) {
                int CA_system_id = in.readInt();
                String name = in.readString();
                return new ParcelableCasPluginDescriptor(CA_system_id, name);
            }

            public ParcelableCasPluginDescriptor[] newArray(int size) {
                return new ParcelableCasPluginDescriptor[size];
            }
        };
    }

    /**
    /**
     * Query if a certain CA system is supported on this device.
     * Query if a certain CA system is supported on this device.
     *
     *
@@ -393,13 +336,14 @@ public final class MediaCas implements AutoCloseable {


        if (service != null) {
        if (service != null) {
            try {
            try {
                ParcelableCasPluginDescriptor[] descriptors = service.enumeratePlugins();
                ArrayList<HidlCasPluginDescriptor> descriptors =
                if (descriptors.length == 0) {
                        service.enumeratePlugins();
                if (descriptors.size() == 0) {
                    return null;
                    return null;
                }
                }
                PluginDescriptor[] results = new PluginDescriptor[descriptors.length];
                PluginDescriptor[] results = new PluginDescriptor[descriptors.size()];
                for (int i = 0; i < results.length; i++) {
                for (int i = 0; i < results.length; i++) {
                    results[i] = descriptors[i];
                    results[i] = new PluginDescriptor(descriptors.get(i));
                }
                }
                return results;
                return results;
            } catch (RemoteException e) {
            } catch (RemoteException e) {
@@ -430,7 +374,7 @@ public final class MediaCas implements AutoCloseable {
        }
        }
    }
    }


    IBinder getBinder() {
    IHwBinder getBinder() {
        validateInternalStates();
        validateInternalStates();


        return mICas.asBinder();
        return mICas.asBinder();
@@ -497,14 +441,22 @@ public final class MediaCas implements AutoCloseable {
        validateInternalStates();
        validateInternalStates();


        try {
        try {
            mICas.setPrivateData(data);
            MediaCasException.throwExceptionIfNeeded(
        } catch (ServiceSpecificException e) {
                    mICas.setPrivateData(toByteArray(data, 0, data.length)));
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
            cleanupAndRethrowIllegalState();
        }
        }
    }
    }


    private class OpenSessionCallback implements ICas.openSessionCallback {
        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
     * Open a session to descramble one or more streams scrambled by the
     * conditional access system.
     * conditional access system.
@@ -519,9 +471,10 @@ public final class MediaCas implements AutoCloseable {
        validateInternalStates();
        validateInternalStates();


        try {
        try {
            return createFromSessionId(mICas.openSession());
            OpenSessionCallback cb = new OpenSessionCallback();
        } catch (ServiceSpecificException e) {
            mICas.openSession(cb);
            MediaCasException.throwExceptions(e);
            MediaCasException.throwExceptionIfNeeded(cb.mStatus);
            return cb.mSession;
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
            cleanupAndRethrowIllegalState();
        }
        }
@@ -544,10 +497,8 @@ public final class MediaCas implements AutoCloseable {
        validateInternalStates();
        validateInternalStates();


        try {
        try {
            mCasData.set(data, offset, length);
            MediaCasException.throwExceptionIfNeeded(
            mICas.processEmm(mCasData);
                    mICas.processEmm(toByteArray(data, offset, length)));
        } catch (ServiceSpecificException e) {
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
            cleanupAndRethrowIllegalState();
        }
        }
@@ -585,9 +536,8 @@ public final class MediaCas implements AutoCloseable {
        validateInternalStates();
        validateInternalStates();


        try {
        try {
            mICas.sendEvent(event, arg, data);
            MediaCasException.throwExceptionIfNeeded(
        } catch (ServiceSpecificException e) {
                    mICas.sendEvent(event, arg, toByteArray(data)));
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
            cleanupAndRethrowIllegalState();
        }
        }
@@ -608,9 +558,8 @@ public final class MediaCas implements AutoCloseable {
        validateInternalStates();
        validateInternalStates();


        try {
        try {
            mICas.provision(provisionString);
            MediaCasException.throwExceptionIfNeeded(
        } catch (ServiceSpecificException e) {
                    mICas.provision(provisionString));
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
            cleanupAndRethrowIllegalState();
        }
        }
@@ -631,9 +580,8 @@ public final class MediaCas implements AutoCloseable {
        validateInternalStates();
        validateInternalStates();


        try {
        try {
            mICas.refreshEntitlements(refreshType, refreshData);
            MediaCasException.throwExceptionIfNeeded(
        } catch (ServiceSpecificException e) {
                    mICas.refreshEntitlements(refreshType, toByteArray(refreshData)));
            MediaCasException.throwExceptions(e);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            cleanupAndRethrowIllegalState();
            cleanupAndRethrowIllegalState();
        }
        }
+14 −45
Original line number Original line Diff line number Diff line
@@ -16,60 +16,29 @@


package android.media;
package android.media;


import android.os.ServiceSpecificException;
import android.hardware.cas.V1_0.Status;


/**
/**
 * Base class for MediaCas exceptions
 * Base class for MediaCas exceptions
 */
 */
public class MediaCasException extends Exception {
public class MediaCasException extends Exception {

    private MediaCasException(String detailMessage) {
    /** @hide */
    public static final int DRM_ERROR_BASE = -2000;
    /** @hide */
    public static final int ERROR_DRM_UNKNOWN                        = DRM_ERROR_BASE;
    /** @hide */
    public static final int ERROR_DRM_NO_LICENSE                     = DRM_ERROR_BASE - 1;
    /** @hide */
    public static final int ERROR_DRM_LICENSE_EXPIRED                = DRM_ERROR_BASE - 2;
    /** @hide */
    public static final int ERROR_DRM_SESSION_NOT_OPENED             = DRM_ERROR_BASE - 3;
    /** @hide */
    public static final int ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED   = DRM_ERROR_BASE - 4;
    /** @hide */
    public static final int ERROR_DRM_DECRYPT                        = DRM_ERROR_BASE - 5;
    /** @hide */
    public static final int ERROR_DRM_CANNOT_HANDLE                  = DRM_ERROR_BASE - 6;
    /** @hide */
    public static final int ERROR_DRM_TAMPER_DETECTED                = DRM_ERROR_BASE - 7;
    /** @hide */
    public static final int ERROR_DRM_NOT_PROVISIONED                = DRM_ERROR_BASE - 8;
    /** @hide */
    public static final int ERROR_DRM_DEVICE_REVOKED                 = DRM_ERROR_BASE - 9;
    /** @hide */
    public static final int ERROR_DRM_RESOURCE_BUSY                  = DRM_ERROR_BASE - 10;
    /** @hide */
    public static final int ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11;
    /** @hide */
    public static final int ERROR_DRM_LAST_USED_ERRORCODE            = DRM_ERROR_BASE - 11;
    /** @hide */
    public static final int ERROR_DRM_VENDOR_MAX                     = DRM_ERROR_BASE - 500;
    /** @hide */
    public static final int ERROR_DRM_VENDOR_MIN                     = DRM_ERROR_BASE - 999;

    /** @hide */
    public MediaCasException(String detailMessage) {
        super(detailMessage);
        super(detailMessage);
    }
    }


    static void throwExceptions(ServiceSpecificException e) throws MediaCasException {
    static void throwExceptionIfNeeded(int error) throws MediaCasException {
        if (e.errorCode == ERROR_DRM_NOT_PROVISIONED) {
        if (error == Status.OK) {
            throw new NotProvisionedException(e.getMessage());
            return;
        } else if (e.errorCode == ERROR_DRM_RESOURCE_BUSY) {
        }
            throw new ResourceBusyException(e.getMessage());

        } else if (e.errorCode == ERROR_DRM_DEVICE_REVOKED) {
        if (error == Status.ERROR_CAS_NOT_PROVISIONED) {
            throw new DeniedByServerException(e.getMessage());
            throw new NotProvisionedException(null);
        } else if (error == Status.ERROR_CAS_RESOURCE_BUSY) {
            throw new ResourceBusyException(null);
        } else if (error == Status.ERROR_CAS_DEVICE_REVOKED) {
            throw new DeniedByServerException(null);
        } else {
        } else {
            MediaCasStateException.throwExceptions(e);
            MediaCasStateException.throwExceptionIfNeeded(error);
        }
        }
    }
    }


+34 −19
Original line number Original line Diff line number Diff line
@@ -18,9 +18,8 @@ package android.media;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.os.ServiceSpecificException;


import static android.media.MediaCasException.*;
import android.hardware.cas.V1_0.Status;


/**
/**
 * Base class for MediaCas runtime exceptions
 * Base class for MediaCas runtime exceptions
@@ -29,46 +28,62 @@ public class MediaCasStateException extends IllegalStateException {
    private final int mErrorCode;
    private final int mErrorCode;
    private final String mDiagnosticInfo;
    private final String mDiagnosticInfo;


    /** @hide */
    private MediaCasStateException(int err, @Nullable String msg, @Nullable String diagnosticInfo) {
    public MediaCasStateException(int err, @Nullable String msg, @Nullable String diagnosticInfo) {
        super(msg);
        super(msg);
        mErrorCode = err;
        mErrorCode = err;
        mDiagnosticInfo = diagnosticInfo;
        mDiagnosticInfo = diagnosticInfo;
    }
    }


    static void throwExceptions(ServiceSpecificException e) {
    static void throwExceptionIfNeeded(int err) {
        throwExceptionIfNeeded(err, null /* msg */);
    }

    static void throwExceptionIfNeeded(int err, @Nullable String msg) {
        if (err == Status.OK) {
            return;
        }
        if (err == Status.BAD_VALUE) {
            throw new IllegalArgumentException();
        }

        String diagnosticInfo = "";
        String diagnosticInfo = "";
        switch (e.errorCode) {
        switch (err) {
        case ERROR_DRM_UNKNOWN:
        case Status.ERROR_CAS_UNKNOWN:
            diagnosticInfo = "General CAS error";
            diagnosticInfo = "General CAS error";
            break;
            break;
        case ERROR_DRM_NO_LICENSE:
        case Status.ERROR_CAS_NO_LICENSE:
            diagnosticInfo = "No license";
            diagnosticInfo = "No license";
            break;
            break;
        case ERROR_DRM_LICENSE_EXPIRED:
        case Status.ERROR_CAS_LICENSE_EXPIRED:
            diagnosticInfo = "License expired";
            diagnosticInfo = "License expired";
            break;
            break;
        case ERROR_DRM_SESSION_NOT_OPENED:
        case Status.ERROR_CAS_SESSION_NOT_OPENED:
            diagnosticInfo = "Session not opened";
            diagnosticInfo = "Session not opened";
            break;
            break;
        case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
        case Status.ERROR_CAS_CANNOT_HANDLE:
            diagnosticInfo = "Not initialized";
            diagnosticInfo = "Unsupported scheme or data format";
            break;
            break;
        case ERROR_DRM_DECRYPT:
        case Status.ERROR_CAS_INVALID_STATE:
            diagnosticInfo = "Decrypt error";
            diagnosticInfo = "Invalid CAS state";
            break;
            break;
        case ERROR_DRM_CANNOT_HANDLE:
        case Status.ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION:
            diagnosticInfo = "Unsupported scheme or data format";
            diagnosticInfo = "Insufficient output protection";
            break;
            break;
        case ERROR_DRM_TAMPER_DETECTED:
        case Status.ERROR_CAS_TAMPER_DETECTED:
            diagnosticInfo = "Tamper detected";
            diagnosticInfo = "Tamper detected";
            break;
            break;
        case Status.ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED:
            diagnosticInfo = "Not initialized";
            break;
        case Status.ERROR_CAS_DECRYPT:
            diagnosticInfo = "Decrypt error";
            break;
        default:
        default:
            diagnosticInfo = "Unknown CAS state exception";
            diagnosticInfo = "Unknown CAS state exception";
            break;
            break;
        }
        }
        throw new MediaCasStateException(e.errorCode, e.getMessage(),
        throw new MediaCasStateException(err, msg,
                String.format("%s (err=%d)", diagnosticInfo, e.errorCode));
                String.format("%s (err=%d)", diagnosticInfo, err));
    }
    }


    /**
    /**
+3 −2
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.media.MediaCodecInfo.CodecCapabilities;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.IHwBinder;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.PersistableBundle;
@@ -1903,7 +1904,7 @@ final public class MediaCodec {


    private void configure(
    private void configure(
            @Nullable MediaFormat format, @Nullable Surface surface,
            @Nullable MediaFormat format, @Nullable Surface surface,
            @Nullable MediaCrypto crypto, @Nullable IBinder descramblerBinder,
            @Nullable MediaCrypto crypto, @Nullable IHwBinder descramblerBinder,
            @ConfigureFlag int flags) {
            @ConfigureFlag int flags) {
        if (crypto != null && descramblerBinder != null) {
        if (crypto != null && descramblerBinder != null) {
            throw new IllegalArgumentException("Can't use crypto and descrambler together!");
            throw new IllegalArgumentException("Can't use crypto and descrambler together!");
@@ -2018,7 +2019,7 @@ final public class MediaCodec {
    private native final void native_configure(
    private native final void native_configure(
            @Nullable String[] keys, @Nullable Object[] values,
            @Nullable String[] keys, @Nullable Object[] values,
            @Nullable Surface surface, @Nullable MediaCrypto crypto,
            @Nullable Surface surface, @Nullable MediaCrypto crypto,
            @Nullable IBinder descramblerBinder, @ConfigureFlag int flags);
            @Nullable IHwBinder descramblerBinder, @ConfigureFlag int flags);


    /**
    /**
     * Requests a Surface to use as the input to an encoder, in place of input buffers.  This
     * Requests a Surface to use as the input to an encoder, in place of input buffers.  This
Loading