107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber/*
207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Copyright (C) 2012 The Android Open Source Project
307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *
407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * you may not use this file except in compliance with the License.
607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * You may obtain a copy of the License at
707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *
807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *
1007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Unless required by applicable law or agreed to in writing, software
1107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * See the License for the specific language governing permissions and
1407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * limitations under the License.
1507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber */
1607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
1707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberpackage android.media;
1807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
1999f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnarimport android.annotation.NonNull;
2060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberimport android.media.MediaCryptoException;
2160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberimport java.util.UUID;
2260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
2307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber/**
2407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * MediaCrypto class can be used in conjunction with {@link android.media.MediaCodec}
2507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * to decode encrypted media data.
2607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *
2707ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * Crypto schemes are assigned 16 byte UUIDs,
2807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * the method {@link #isCryptoSchemeSupported} can be used to query if a given
2907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber * scheme is supported on the device.
3007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber *
3160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */
3207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huberpublic final class MediaCrypto {
3360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    /**
3460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * Query if the given scheme identified by its UUID is supported on
3560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * this device.
3660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * @param uuid The UUID of the crypto scheme.
3760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     */
3899f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    public static final boolean isCryptoSchemeSupported(@NonNull UUID uuid) {
3960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid));
4060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
4160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
4299f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    @NonNull
4399f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    private static final byte[] getByteArrayFromUUID(@NonNull UUID uuid) {
4460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        long msb = uuid.getMostSignificantBits();
4560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        long lsb = uuid.getLeastSignificantBits();
4660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
4760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        byte[] uuidBytes = new byte[16];
4860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        for (int i = 0; i < 8; ++i) {
4960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber            uuidBytes[i] = (byte)(msb >>> (8 * (7 - i)));
5060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber            uuidBytes[8 + i] = (byte)(lsb >>> (8 * (7 - i)));
5160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        }
5207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
5360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        return uuidBytes;
5407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
5507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
5699f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    private static final native boolean isCryptoSchemeSupportedNative(@NonNull byte[] uuid);
5760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
5860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    /**
5960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * Instantiate a MediaCrypto object using opaque, crypto scheme specific
6060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * data.
6160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * @param uuid The UUID of the crypto scheme.
6260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * @param initData Opaque initialization data specific to the crypto scheme.
6360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     */
6499f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    public MediaCrypto(@NonNull UUID uuid, @NonNull byte[] initData) throws MediaCryptoException {
6560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        native_setup(getByteArrayFromUUID(uuid), initData);
6660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
6760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
6860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    /**
6960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * Query if the crypto scheme requires the use of a secure decoder
7060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * to decode data of the given mime type.
7160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * @param mime The mime type of the media data
7260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     */
7399f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    public final native boolean requiresSecureDecoderComponent(@NonNull String mime);
7407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
756f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker    /**
766f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * Associate a MediaDrm session with this MediaCrypto instance.  The
776f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * MediaDrm session is used to securely load decryption keys for a
786f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * crypto scheme.  The crypto keys loaded through the MediaDrm session
796f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * may be selected for use during the decryption operation performed
806f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * by {@link android.media.MediaCodec#queueSecureInputBuffer} by specifying
816f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * their key ids in the {@link android.media.MediaCodec.CryptoInfo#key} field.
826f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * @param sessionId the MediaDrm sessionId to associate with this
836f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * MediaCrypto instance
846f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     * @throws MediaCryptoException on failure to set the sessionId
856f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker     */
8699f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    public final native void setMediaDrmSession(@NonNull byte[] sessionId)
876f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker        throws MediaCryptoException;
886f6ef118a791c0f888db4addc6543e1f67700eadJeff Tinker
8907ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    @Override
9007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    protected void finalize() {
9107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        native_finalize();
9207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
9307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
9407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    public native final void release();
9507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    private static native final void native_init();
9660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
9799f8072386ce9891a5973d591dc1a30e45b50bc6Lajos Molnar    private native final void native_setup(@NonNull byte[] uuid, @NonNull byte[] initData)
9860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        throws MediaCryptoException;
9960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
10007ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    private native final void native_finalize();
10107ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
10207ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    static {
10307ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        System.loadLibrary("media_jni");
10407ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber        native_init();
10507ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber    }
10607ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber
107075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    private long mNativeContext;
10807ea426e3ae8915ca6bf67135f523f42cd920af0Andreas Huber}
109