FileDocCategorySizeDatePackage
DrmWrapper.javaAPI DocAndroid 1.5 API7075Wed May 06 22:42:46 BST 2009com.android.mms.drm

DrmWrapper.java

/*
 * Copyright (C) 2007-2008 Esmertec AG.
 * Copyright (C) 2007-2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mms.drm;

import com.google.android.mms.ContentType;

import android.drm.mobile1.DrmException;
import android.drm.mobile1.DrmRawContent;
import android.drm.mobile1.DrmRights;
import android.drm.mobile1.DrmRightsManager;
import android.net.Uri;
import android.util.Config;
import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * The Drm Wrapper.
 */
public class DrmWrapper {
    /**
     * The DRM right object.
     */
    private DrmRights mRight;

    /**
     * The DrmRawContent.
     */
    private final DrmRawContent mDrmObject;

    private final Uri mDataUri;
    private final byte[] mData;
    /**
     * The decrypted data.
     */
    private byte[] mDecryptedData;

    /**
     * The log tag.
     */
    private static final String LOG_TAG = "DrmWrapper";
    private static final boolean DEBUG = false;
    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;

    /**
     * Constructor.
     * @param uri
     */
    public DrmWrapper(String drmContentType, Uri uri, byte[] drmData)
            throws DrmException, IOException {
        if ((drmContentType == null) || (drmData == null)) {
            throw new IllegalArgumentException(
                    "Content-Type or data may not be null.");
        }

        mDataUri = uri;
        mData = drmData;

        ByteArrayInputStream drmDataStream = new ByteArrayInputStream(drmData);
        mDrmObject = new DrmRawContent(drmDataStream, drmDataStream.available(),
                                       drmContentType);
        // Install rights if necessary.
        if (!isRightsInstalled()) {
            if (LOCAL_LOGV) {
                Log.v(LOG_TAG, "DRM rights not installed yet.");
            }
            installRights(drmData);
        }
    }

    /**
     * Get permission type for the decrypted content-type.
     *
     * @return the permission
     */
    private int getPermission() {
        String contentType = mDrmObject.getContentType();

        if (ContentType.isAudioType(contentType) ||
                ContentType.isVideoType(contentType)) {
            return DrmRights.DRM_PERMISSION_PLAY;
        }
        return DrmRights.DRM_PERMISSION_DISPLAY;
    }

    /**
     * Get decrypted data.
     *
     * @return the decrypted content if decryption was successful.
     * @throws IOException
     */
    public byte[] getDecryptedData() throws IOException {
        if ((mDecryptedData == null) && (mRight != null)) {
            // Decrypt it.
            InputStream decryptedDataStream = mDrmObject.getContentInputStream(mRight);
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[256];
                int len;
                while ((len = decryptedDataStream.read(buffer)) > 0) {
                    baos.write(buffer, 0, len);
                }
                mDecryptedData = baos.toByteArray();
            } finally {
                try {
                    decryptedDataStream.close();
                } catch (IOException e) {
                    Log.e(LOG_TAG, e.getMessage(), e);
                }
            }
        }

        if (mDecryptedData != null) {
            byte[] decryptedData = new byte[mDecryptedData.length];
            System.arraycopy(mDecryptedData, 0, decryptedData, 0, mDecryptedData.length);
            return decryptedData;
        }
        return null;
    }

    /**
     * Consume the rights.
     *
     * @return true if consume success
     *         false if consume failure
     */
    public boolean consumeRights() {
        if (mRight == null) {
            return false;
        }

        return mRight.consumeRights(getPermission());
    }

    /**
     * Install Right.
     *
     * @param rightData right's data
     * @throws IOException
     * @throws DrmException
     */
    public void installRights(byte[] rightData) throws DrmException, IOException {
        if (rightData == null) {
            throw new DrmException("Right data may not be null.");
        }

        if (LOCAL_LOGV) {
            Log.v(LOG_TAG, "Installing DRM rights.");
        }

        ByteArrayInputStream rightDataStream = new ByteArrayInputStream(rightData);
        mRight = DrmRightsManager.getInstance().installRights(
                rightDataStream, rightData.length,
                DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING);
    }

    /**
     * Check whether the DRM object's right is existed. If not, we should
     * download it.
     *
     * @return true if it is existed
     *         false if not
     */
    public boolean isRightsInstalled() {
        if (mRight != null) {
            return true;
        }

        mRight = DrmRightsManager.getInstance().queryRights(mDrmObject);
        return mRight != null ? true : false;
    }

    /**
     * Check whether this DRM object can be forwarded.
     *
     * @return true if this object can be forwarded
     *         false if not
     */
    public boolean isAllowedToForward() {
        if (DrmRawContent.DRM_SEPARATE_DELIVERY != mDrmObject.getRawType()) {
            return false;
        }
        return true;
    }

    /**
     * Check whether a object is DRM object.
     *
     * @param contentType the mimetype of the object
     * @return true if it is
     *         false if not
     */
    public static boolean isDrmObject(String contentType) {
        if (contentType == null) {
            return false;
        }

        if (contentType.equalsIgnoreCase(DrmRawContent.DRM_MIMETYPE_CONTENT_STRING) ||
                contentType.equalsIgnoreCase(DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING)) {
            return true;
        }

        return false;
    }

    /**
     * Get URL of right.
     *
     * @return the right's URL
     */
    public String getRightsAddress() {
        if (mDrmObject == null) {
            return null;
        }
        return mDrmObject.getRightsAddress();
    }

    /**
     * Get the decrypted object's content-type.
     *
     * @return the content-type
     */
    public String getContentType() {
        return mDrmObject.getContentType();
    }

    public Uri getOriginalUri() {
        return mDataUri;
    }

    public byte[] getOriginalData() {
        return mData;
    }
}