diff options
Diffstat (limited to 'drm')
-rw-r--r-- | drm/java/android/drm/DrmManagerClient.java | 29 | ||||
-rw-r--r-- | drm/java/android/drm/DrmOutputStream.java | 104 |
2 files changed, 124 insertions, 9 deletions
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java index 2907f10..10cdab0 100644 --- a/drm/java/android/drm/DrmManagerClient.java +++ b/drm/java/android/drm/DrmManagerClient.java @@ -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(); } /** diff --git a/drm/java/android/drm/DrmOutputStream.java b/drm/java/android/drm/DrmOutputStream.java new file mode 100644 index 0000000..2e1b756 --- /dev/null +++ b/drm/java/android/drm/DrmOutputStream.java @@ -0,0 +1,104 @@ +/* + * 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 }); + } +} |