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

Commit 6fd651eb authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Move DRM to CloseGuard, add DrmOutputStream."

parents bd008614 f67c8a96
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;

import dalvik.system.CloseGuard;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -52,10 +54,15 @@ public class DrmManagerClient {
     */
    public static final int ERROR_UNKNOWN = -2000;

    /** {@hide} */
    public static final int INVALID_SESSION = -1;

    HandlerThread mInfoThread;
    HandlerThread mEventThread;
    private static final String TAG = "DrmManagerClient";

    private final CloseGuard mCloseGuard = CloseGuard.get();

    static {
        // Load the respective library
        System.loadLibrary("drmframework_jni");
@@ -110,7 +117,7 @@ public class DrmManagerClient {

    private int mUniqueId;
    private int mNativeContext;
    private boolean mReleased;
    private volatile boolean mReleased;
    private Context mContext;
    private InfoHandler mInfoHandler;
    private EventHandler mEventHandler;
@@ -244,17 +251,22 @@ public class DrmManagerClient {
     */
    public DrmManagerClient(Context context) {
        mContext = context;
        mReleased = false;
        createEventThreads();

        // save the unique id
        mUniqueId = _initialize();
        mCloseGuard.open("release");
    }

    protected void finalize() {
        if (!mReleased) {
            Log.w(TAG, "You should have called release()");
    @Override
    protected void finalize() throws Throwable {
        try {
            if (mCloseGuard != null) {
                mCloseGuard.warnIfOpen();
            }
            release();
        } finally {
            super.finalize();
        }
    }

@@ -266,11 +278,9 @@ public class DrmManagerClient {
     * {@link DrmManagerClient} is no longer usable since it has lost all of its required resource.
     */
    public void release() {
        if (mReleased) {
            Log.w(TAG, "You have already called release()");
            return;
        }
        if (mReleased) return;
        mReleased = true;

        if (mEventHandler != null) {
            mEventThread.quit();
            mEventThread = null;
@@ -285,6 +295,7 @@ public class DrmManagerClient {
        mOnInfoListener = null;
        mOnErrorListener = null;
        _release(mUniqueId);
        mCloseGuard.close();
    }

    /**
+104 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 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 android.drm;

import static android.drm.DrmConvertedStatus.STATUS_OK;

import java.io.File;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.UnknownServiceException;
import java.util.Arrays;

import libcore.io.IoUtils;
import libcore.util.SneakyThrow;

/**
 * Stream that applies a {@link DrmManagerClient} transformation to data before
 * writing to disk, similar to a {@link FilterOutputStream}.
 *
 * @hide
 */
public class DrmOutputStream extends OutputStream {

    private final DrmManagerClient mClient;

    private int mSessionId;
    private RandomAccessFile mOutput;

    public DrmOutputStream(DrmManagerClient client, File file, String mimeType) throws IOException {
        mClient = client;
        mOutput = new RandomAccessFile(file, "rw");

        try {
            mSessionId = mClient.openConvertSession(mimeType);
            if (mSessionId == DrmManagerClient.INVALID_SESSION) {
                throw new UnknownServiceException("Failed to open DRM session for " + mimeType);
            }
        } catch (Throwable thrown) {
            IoUtils.closeQuietly(mOutput);
            SneakyThrow.sneakyThrow(thrown);
        }
    }

    @Override
    public void close() throws IOException {
        try {
            final DrmConvertedStatus status = mClient.closeConvertSession(mSessionId);
            if (status.statusCode == STATUS_OK) {
                mOutput.seek(status.offset);
                mOutput.write(status.convertedData);
            } else {
                throw new IOException("Unexpected DRM status: " + status.statusCode);
            }
        } finally {
            try {
                mOutput.getFD().sync();
            } finally {
                mOutput.close();
                mOutput = null;
            }
        }
    }

    @Override
    public void write(byte[] buffer, int offset, int count) throws IOException {
        Arrays.checkOffsetAndCount(buffer.length, offset, count);

        final byte[] exactBuffer;
        if (count == buffer.length) {
            exactBuffer = buffer;
        } else {
            exactBuffer = new byte[count];
            System.arraycopy(buffer, offset, exactBuffer, 0, count);
        }

        final DrmConvertedStatus status = mClient.convertData(mSessionId, exactBuffer);
        if (status.statusCode == STATUS_OK) {
            mOutput.write(status.convertedData);
        } else {
            throw new IOException("Unexpected DRM status: " + status.statusCode);
        }
    }

    @Override
    public void write(int oneByte) throws IOException {
        write(new byte[] { (byte) oneByte });
    }
}