1d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi/*
2d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Copyright (C) 2010 The Android Open Source Project
3d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
4d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
5d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * you may not use this file except in compliance with the License.
6d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * You may obtain a copy of the License at
7d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
8d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
9d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
10d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * Unless required by applicable law or agreed to in writing, software
11d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
12d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * See the License for the specific language governing permissions and
14d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi * limitations under the License.
15d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi */
16d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
17d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshipackage android.drm;
18d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
19c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimiimport android.content.ContentResolver;
20d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport android.content.ContentValues;
21d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport android.content.Context;
22dc549d60f98d809f626c99de614960409a847054Takeshi Aimiimport android.database.Cursor;
23c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimiimport android.database.sqlite.SQLiteException;
24dc549d60f98d809f626c99de614960409a847054Takeshi Aimiimport android.net.Uri;
25d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport android.os.Handler;
26dc549d60f98d809f626c99de614960409a847054Takeshi Aimiimport android.os.HandlerThread;
27d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport android.os.Looper;
28d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport android.os.Message;
29dc549d60f98d809f626c99de614960409a847054Takeshi Aimiimport android.provider.MediaStore;
30d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport android.util.Log;
31d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
32f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkeyimport dalvik.system.CloseGuard;
33f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey
340889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dongimport java.io.File;
350889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dongimport java.io.FileDescriptor;
360889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dongimport java.io.FileInputStream;
37d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport java.io.IOException;
38d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport java.lang.ref.WeakReference;
39d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport java.util.ArrayList;
40dc549d60f98d809f626c99de614960409a847054Takeshi Aimiimport java.util.HashMap;
4160cfad80bdf61db436643927337c2fb30186e99dJeff Sharkeyimport java.util.concurrent.atomic.AtomicBoolean;
42d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
43d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi/**
440e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber * The main programming interface for the DRM framework. An application must instantiate this class
450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber * to access DRM agents through the DRM framework.
46d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
47d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi */
4860cfad80bdf61db436643927337c2fb30186e99dJeff Sharkeypublic class DrmManagerClient implements AutoCloseable {
49dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
500e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Indicates that a request was successful or that no error occurred.
51dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
52dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public static final int ERROR_NONE = 0;
53dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
540e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Indicates that an error occurred and the reason is not known.
55dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
56dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public static final int ERROR_UNKNOWN = -2000;
57dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
58f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey    /** {@hide} */
59f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey    public static final int INVALID_SESSION = -1;
60f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey
616225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    HandlerThread mInfoThread;
626225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    HandlerThread mEventThread;
63dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private static final String TAG = "DrmManagerClient";
64d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
6560cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    private final AtomicBoolean mClosed = new AtomicBoolean();
66f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey    private final CloseGuard mCloseGuard = CloseGuard.get();
67f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey
68d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static {
69d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        // Load the respective library
70d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        System.loadLibrary("drmframework_jni");
71d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
72d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
73d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
740e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Interface definition for a callback that receives status messages and warnings
750e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * during registration and rights acquisition.
76d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
77d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public interface OnInfoListener {
78d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        /**
790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * Called when the DRM framework sends status or warning information during registration
800e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * and rights acquisition.
81d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi         *
820e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param client The <code>DrmManagerClient</code> instance.
830e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param event The {@link DrmInfoEvent} instance that wraps the status information or
840e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * warnings.
85d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi         */
86d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        public void onInfo(DrmManagerClient client, DrmInfoEvent event);
87d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
88d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
89dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
900e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Interface definition for a callback that receives information
910e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * about DRM processing events.
92dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
93dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public interface OnEventListener {
94dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        /**
950e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * Called when the DRM framework sends information about a DRM processing request.
96dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         *
970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param client The <code>DrmManagerClient</code> instance.
980e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param event The {@link DrmEvent} instance that wraps the information being
990e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * conveyed, such as the information type and message.
100dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         */
101f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang        public void onEvent(DrmManagerClient client, DrmEvent event);
102dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
103dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
104dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
1050e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Interface definition for a callback that receives information about DRM framework errors.
106dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
107dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public interface OnErrorListener {
108dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        /**
1090e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * Called when the DRM framework sends error information.
110dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         *
1110e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param client The <code>DrmManagerClient</code> instance.
1120e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param event The {@link DrmErrorEvent} instance that wraps the error type and message.
113dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         */
114dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public void onError(DrmManagerClient client, DrmErrorEvent event);
115dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
116dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
117c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    private static final int ACTION_REMOVE_ALL_RIGHTS = 1001;
118dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    private static final int ACTION_PROCESS_DRM_INFO = 1002;
119d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
120d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private int mUniqueId;
12133d603877acf76d5d59484532025af20f4b068a5Ashok Bhat    private long mNativeContext;
122dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private Context mContext;
123dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private InfoHandler mInfoHandler;
124d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private EventHandler mEventHandler;
125d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private OnInfoListener mOnInfoListener;
126dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private OnEventListener mOnEventListener;
127dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private OnErrorListener mOnErrorListener;
128d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
129dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private class EventHandler extends Handler {
130dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
131dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public EventHandler(Looper looper) {
132dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            super(looper);
133dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
134dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
135dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public void handleMessage(Message msg) {
136dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            DrmEvent event = null;
137dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            DrmErrorEvent error = null;
138dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            HashMap<String, Object> attributes = new HashMap<String, Object>();
139dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
140dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            switch(msg.what) {
141dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            case ACTION_PROCESS_DRM_INFO: {
142dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                final DrmInfo drmInfo = (DrmInfo) msg.obj;
143dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                DrmInfoStatus status = _processDrmInfo(mUniqueId, drmInfo);
144f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang
145f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                attributes.put(DrmEvent.DRM_INFO_STATUS_OBJECT, status);
146f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                attributes.put(DrmEvent.DRM_INFO_OBJECT, drmInfo);
147f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang
148dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (null != status && DrmInfoStatus.STATUS_OK == status.statusCode) {
149f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                    event = new DrmEvent(mUniqueId,
150f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                            getEventType(status.infoType), null, attributes);
151dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                } else {
152c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                    int infoType = (null != status) ? status.infoType : drmInfo.getInfoType();
153f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                    error = new DrmErrorEvent(mUniqueId,
154f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                            getErrorType(infoType), null, attributes);
155dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
156dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                break;
157dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
158dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            case ACTION_REMOVE_ALL_RIGHTS: {
159dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (ERROR_NONE == _removeAllRights(mUniqueId)) {
160dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_ALL_RIGHTS_REMOVED, null);
161dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                } else {
162dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    error = new DrmErrorEvent(mUniqueId,
163dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                            DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED, null);
164dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
165dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                break;
166dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
167dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            default:
168dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                Log.e(TAG, "Unknown message type " + msg.what);
169dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                return;
170dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
171dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            if (null != mOnEventListener && null != event) {
172f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                mOnEventListener.onEvent(DrmManagerClient.this, event);
173dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
174dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            if (null != mOnErrorListener && null != error) {
175dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                mOnErrorListener.onError(DrmManagerClient.this, error);
176dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
177dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
178dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
179dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
180d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
181d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     * {@hide}
182d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
183dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public static void notify(
184dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Object thisReference, int uniqueId, int infoType, String message) {
185d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmManagerClient instance = (DrmManagerClient)((WeakReference)thisReference).get();
186d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
187dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != instance && null != instance.mInfoHandler) {
188dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Message m = instance.mInfoHandler.obtainMessage(
189dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                InfoHandler.INFO_EVENT_TYPE, uniqueId, infoType, message);
190dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            instance.mInfoHandler.sendMessage(m);
191d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
192d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
193d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
194dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private class InfoHandler extends Handler {
195d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        public static final int INFO_EVENT_TYPE = 1;
196d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
197dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public InfoHandler(Looper looper) {
198d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            super(looper);
199d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
200d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
201d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        public void handleMessage(Message msg) {
20227b277779c89251f2aafcc7a56db95d264900c9dGloria Wang            DrmInfoEvent info = null;
203dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            DrmErrorEvent error = null;
204d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
205d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            switch (msg.what) {
206dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            case InfoHandler.INFO_EVENT_TYPE:
207d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                int uniqueId = msg.arg1;
208d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                int infoType = msg.arg2;
209d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                String message = msg.obj.toString();
210d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
211dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                switch (infoType) {
212dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                case DrmInfoEvent.TYPE_REMOVE_RIGHTS: {
213d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    try {
214d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                        DrmUtils.removeFile(message);
215d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    } catch (IOException e) {
216d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                        e.printStackTrace();
217d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    }
21827b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                    info = new DrmInfoEvent(uniqueId, infoType, message);
219dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
220dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
22127b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT:
22227b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_RIGHTS_INSTALLED:
22327b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_WAIT_FOR_RIGHTS:
22427b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_ACCOUNT_ALREADY_REGISTERED:
22527b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_RIGHTS_REMOVED: {
22627b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                    info = new DrmInfoEvent(uniqueId, infoType, message);
227dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
228dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
229dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                default:
230dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    error = new DrmErrorEvent(uniqueId, infoType, message);
231dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
232d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                }
233d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
23427b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                if (null != mOnInfoListener && null != info) {
23527b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                    mOnInfoListener.onInfo(DrmManagerClient.this, info);
236d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                }
237dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (null != mOnErrorListener && null != error) {
238dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    mOnErrorListener.onError(DrmManagerClient.this, error);
239dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
240d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                return;
241d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            default:
242d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                Log.e(TAG, "Unknown message type " + msg.what);
243d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                return;
244d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
245d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
246d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
247d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
248d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
2490e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Creates a <code>DrmManagerClient</code>.
250d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
2510e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param context Context of the caller.
252d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
253d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public DrmManagerClient(Context context) {
254dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        mContext = context;
255011385508726fef027641fcbb3e4e446efc9af2cJames Dong        createEventThreads();
256dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
257d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        // save the unique id
2586225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mUniqueId = _initialize();
259f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey        mCloseGuard.open("release");
260c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
261c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi
262f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey    @Override
263f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey    protected void finalize() throws Throwable {
264f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey        try {
265492e9e851cadca62df84eaff1a3c1ba788492fbaNarayan Kamath            if (mCloseGuard != null) {
266492e9e851cadca62df84eaff1a3c1ba788492fbaNarayan Kamath                mCloseGuard.warnIfOpen();
267492e9e851cadca62df84eaff1a3c1ba788492fbaNarayan Kamath            }
268492e9e851cadca62df84eaff1a3c1ba788492fbaNarayan Kamath
26960cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            close();
270f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey        } finally {
271f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey            super.finalize();
2726225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        }
2736225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    }
2746225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
2756225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    /**
27660cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     * Releases resources associated with the current session of
27760cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     * DrmManagerClient. It is considered good practice to call this method when
27860cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     * the {@link DrmManagerClient} object is no longer needed in your
27960cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     * application. After this method is called, {@link DrmManagerClient} is no
28060cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     * longer usable since it has lost all of its required resource.
2815d9a8acdac056e8842d010edd26496960f2a7a8dJeff Tinker     *
2825d9a8acdac056e8842d010edd26496960f2a7a8dJeff Tinker     * This method was added in API 24. In API versions 16 through 23, release()
2835d9a8acdac056e8842d010edd26496960f2a7a8dJeff Tinker     * should be called instead. There is no need to do anything for API
2845d9a8acdac056e8842d010edd26496960f2a7a8dJeff Tinker     * versions prior to 16.
2856225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     */
28660cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    @Override
28760cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    public void close() {
288f67c8a9685e0f20d5ffb9de95f6d1ce47f052141Jeff Sharkey        mCloseGuard.close();
28960cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey        if (mClosed.compareAndSet(false, true)) {
29060cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            if (mEventHandler != null) {
29160cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey                mEventThread.quit();
29260cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey                mEventThread = null;
29360cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            }
29460cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            if (mInfoHandler != null) {
29560cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey                mInfoThread.quit();
29660cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey                mInfoThread = null;
29760cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            }
29860cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            mEventHandler = null;
29960cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            mInfoHandler = null;
30060cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            mOnEventListener = null;
30160cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            mOnInfoListener = null;
30260cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            mOnErrorListener = null;
30360cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey            _release(mUniqueId);
30460cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey        }
30560cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    }
30660cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey
30760cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    /**
30860cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     * @deprecated replaced by {@link #close()}.
30960cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey     */
31060cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    @Deprecated
31160cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey    public void release() {
31260cfad80bdf61db436643927337c2fb30186e99dJeff Sharkey        close();
313d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
314d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
315d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
3160e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Registers an {@link DrmManagerClient.OnInfoListener} callback, which is invoked when the
3170e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * DRM framework sends status or warning information during registration or rights acquisition.
318d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
3190e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param infoListener Interface definition for the callback.
320d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
321dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public synchronized void setOnInfoListener(OnInfoListener infoListener) {
3226225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnInfoListener = infoListener;
323dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != infoListener) {
3246225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            createListeners();
325dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
326dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
327dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
328dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
3290e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Registers an {@link DrmManagerClient.OnEventListener} callback, which is invoked when the
3300e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * DRM framework sends information about DRM processing.
331dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
3320e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param eventListener Interface definition for the callback.
333dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
334dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public synchronized void setOnEventListener(OnEventListener eventListener) {
3356225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnEventListener = eventListener;
336dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != eventListener) {
3376225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            createListeners();
338dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
339dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
340dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
341dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
3420e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Registers an {@link DrmManagerClient.OnErrorListener} callback, which is invoked when
3430e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the DRM framework sends error information.
344dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
3450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param errorListener Interface definition for the callback.
346dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
347dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public synchronized void setOnErrorListener(OnErrorListener errorListener) {
3486225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnErrorListener = errorListener;
349dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != errorListener) {
3506225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            createListeners();
351d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
352d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
353d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
354d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
3550e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves information about all the DRM plug-ins (agents) that are registered with
3560e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the DRM framework.
357d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
3580e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A <code>String</code> array of DRM plug-in descriptions.
359d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
360d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public String[] getAvailableDrmEngines() {
361d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmSupportInfo[] supportInfos = _getAllSupportInfo(mUniqueId);
362d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        ArrayList<String> descriptions = new ArrayList<String>();
363d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
364d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (int i = 0; i < supportInfos.length; i++) {
365d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            descriptions.add(supportInfos[i].getDescriprition());
366d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
367d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
368d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        String[] drmEngines = new String[descriptions.size()];
369d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return descriptions.toArray(drmEngines);
370d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
371d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
372d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
3730e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves constraint information for rights-protected content.
374d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
3750e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the content from which you are retrieving DRM constraints.
3760e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action Action defined in {@link DrmStore.Action}.
3770e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
3780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link android.content.ContentValues} instance that contains
3790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * key-value pairs representing the constraints. Null in case of failure.
380365ce1db339db53cd5afb118ff867fe940644e45James Dong     * The keys are defined in {@link DrmStore.ConstraintsColumns}.
381d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
382d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public ContentValues getConstraints(String path, int action) {
383d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
384d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given usage or path is invalid/null");
385d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
386d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _getConstraints(mUniqueId, path, action);
387d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
388d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
389dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi   /**
3900e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * Retrieves metadata information for rights-protected content.
3910e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    *
3920e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @param path Path to the content from which you are retrieving metadata information.
393dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    *
3940e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @return A {@link android.content.ContentValues} instance that contains
3950e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * key-value pairs representing the metadata. Null in case of failure.
396dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    */
397dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public ContentValues getMetadata(String path) {
398dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        if (null == path || path.equals("")) {
399dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            throw new IllegalArgumentException("Given path is invalid/null");
400dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        }
401dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return _getMetadata(mUniqueId, path);
402dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
403dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
404d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4050e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves constraint information for rights-protected content.
4060e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4070e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the content from which you are retrieving DRM constraints.
4080e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action Action defined in {@link DrmStore.Action}.
409dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
4100e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link android.content.ContentValues} instance that contains
4110e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * key-value pairs representing the constraints. Null in case of failure.
412dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
413dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public ContentValues getConstraints(Uri uri, int action) {
414c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
415c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            throw new IllegalArgumentException("Uri should be non null");
416c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
417dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return getConstraints(convertUriToPath(uri), action);
418dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
419dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
420dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi   /**
4210e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * Retrieves metadata information for rights-protected content.
422dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    *
4230e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @param uri URI for the content from which you are retrieving metadata information.
4240e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    *
4250e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @return A {@link android.content.ContentValues} instance that contains
4260e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * key-value pairs representing the constraints. Null in case of failure.
427dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    */
428dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public ContentValues getMetadata(Uri uri) {
429dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
430dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            throw new IllegalArgumentException("Uri should be non null");
431dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        }
432dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return getMetadata(convertUriToPath(uri));
433dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
434dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
435dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
4360e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Saves rights to a specified path and associates that path with the content path.
4370e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4380e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * <p class="note"><strong>Note:</strong> For OMA or WM-DRM, <code>rightsPath</code> and
4390e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * <code>contentPath</code> can be null.</p>
4400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4410e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmRights The {@link DrmRights} to be saved.
4420e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param rightsPath File path where rights will be saved.
4430e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param contentPath File path where content is saved.
444d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
4450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
446b01e10c5bc0a29d1b0da96783b6d1582baeb2af2Joe Onorato     *
4470e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @throws IOException If the call failed to save rights information at the given
4480e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * <code>rightsPath</code>.
449d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
450dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int saveRights(
451d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            DrmRights drmRights, String rightsPath, String contentPath) throws IOException {
452dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == drmRights || !drmRights.isValid()) {
453d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given drmRights or contentPath is not valid");
454d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
455d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null != rightsPath && !rightsPath.equals("")) {
456d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            DrmUtils.writeToFile(rightsPath, drmRights.getData());
457d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
458dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return _saveRights(mUniqueId, drmRights, rightsPath, contentPath);
459d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
460d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
461d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4620e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Installs a new DRM plug-in (agent) at runtime.
4630e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4640e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param engineFilePath File path to the plug-in file to be installed.
465d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
466d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     * {@hide}
467d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
468d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public void installDrmEngine(String engineFilePath) {
469d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == engineFilePath || engineFilePath.equals("")) {
470d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException(
471d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                "Given engineFilePath: "+ engineFilePath + "is not valid");
472d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
473d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        _installDrmEngine(mUniqueId, engineFilePath);
474d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
475d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
476d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4770e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given MIME type or path can be handled.
4780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path of the content to be handled.
4800e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the object to be handled.
481d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
4820e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return True if the given MIME type or path can be handled; false if they cannot be handled.
483d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
484d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public boolean canHandle(String path, String mimeType) {
485d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
486d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Path or the mimetype should be non null");
487d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
488d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _canHandle(mUniqueId, path, mimeType);
489d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
490d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
491d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4920e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given MIME type or URI can be handled.
4930e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4940e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the content to be handled.
4950e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the object to be handled
496dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
4970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return True if the given MIME type or URI can be handled; false if they cannot be handled.
498dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
499dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public boolean canHandle(Uri uri, String mimeType) {
500dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
501dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Uri or the mimetype should be non null");
502dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
503dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return canHandle(convertUriToPath(uri), mimeType);
504dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
505dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
506dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
5070e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Processes the given DRM information based on the information type.
508d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
5090e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmInfo The {@link DrmInfo} to be processed.
5100e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
511d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
512dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int processDrmInfo(DrmInfo drmInfo) {
513d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == drmInfo || !drmInfo.isValid()) {
514d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given drmInfo is invalid/null");
515d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
516dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int result = ERROR_UNKNOWN;
517dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != mEventHandler) {
518dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Message msg = mEventHandler.obtainMessage(ACTION_PROCESS_DRM_INFO, drmInfo);
519dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
520dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
521dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return result;
522d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
523d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
524d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
5250e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves information for registering, unregistering, or acquiring rights.
526d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
5270e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmInfoRequest The {@link DrmInfoRequest} that specifies the type of DRM
5280e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * information being retrieved.
5290e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5300e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link DrmInfo} instance.
531d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
532dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public DrmInfo acquireDrmInfo(DrmInfoRequest drmInfoRequest) {
533d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == drmInfoRequest || !drmInfoRequest.isValid()) {
534d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given drmInfoRequest is invalid/null");
535d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
536dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return _acquireDrmInfo(mUniqueId, drmInfoRequest);
537dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
538dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
539dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    /**
5400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Processes a given {@link DrmInfoRequest} and returns the rights information asynchronously.
5410e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *<p>
5420e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * This is a utility method that consists of an
5430e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #acquireDrmInfo(DrmInfoRequest) acquireDrmInfo()} and a
5440e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #processDrmInfo(DrmInfo) processDrmInfo()} method call. This utility method can be
5450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * used only if the selected DRM plug-in (agent) supports this sequence of calls. Some DRM
5460e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * agents, such as OMA, do not support this utility method, in which case an application must
5470e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * invoke {@link #acquireDrmInfo(DrmInfoRequest) acquireDrmInfo()} and
5480e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #processDrmInfo(DrmInfo) processDrmInfo()} separately.
549dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi     *
5500e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmInfoRequest The {@link DrmInfoRequest} used to acquire the rights.
5510e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
552dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi     */
553dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public int acquireRights(DrmInfoRequest drmInfoRequest) {
554dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        DrmInfo drmInfo = acquireDrmInfo(drmInfoRequest);
5554ef690a38b1dfdff3ae34e260435edcec37e520fGloria Wang        if (null == drmInfo) {
5564ef690a38b1dfdff3ae34e260435edcec37e520fGloria Wang            return ERROR_UNKNOWN;
5574ef690a38b1dfdff3ae34e260435edcec37e520fGloria Wang        }
558dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return processDrmInfo(drmInfo);
559d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
560d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
561d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
5620e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the type of rights-protected object (for example, content object, rights
5630e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * object, and so on) using the specified path or MIME type. At least one parameter must
5640e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * be specified to retrieve the DRM object type.
565d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
5660e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the content or null.
5670e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the content or null.
5680e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5690e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> that corresponds to a {@link DrmStore.DrmObjectType}.
570d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
571d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int getDrmObjectType(String path, String mimeType) {
572d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
573d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Path or the mimetype should be non null");
574d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
575d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _getDrmObjectType(mUniqueId, path, mimeType);
576d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
577d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
578d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
5790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the type of rights-protected object (for example, content object, rights
5800e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * object, and so on) using the specified URI or MIME type. At least one parameter must
5810e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * be specified to retrieve the DRM object type.
582dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
5830e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the content or null.
5840e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the content or null.
5850e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5860e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> that corresponds to a {@link DrmStore.DrmObjectType}.
587dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
588dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int getDrmObjectType(Uri uri, String mimeType) {
589dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
590dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Uri or the mimetype should be non null");
591dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
592dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        String path = "";
593dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        try {
594dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            path = convertUriToPath(uri);
595dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        } catch (Exception e) {
596dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            // Even uri is invalid the mimetype shall be valid, so allow to proceed further.
597dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Log.w(TAG, "Given Uri could not be found in media store");
598dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
599dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return getDrmObjectType(path, mimeType);
600dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
601dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
602dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6030e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the MIME type embedded in the original content.
6040e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6050e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
606d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
6070e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return The MIME type of the original content, such as <code>video/mpeg</code>.
608d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
609d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public String getOriginalMimeType(String path) {
610d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("")) {
611d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given path should be non null");
612d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
6130889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong
6140889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        String mime = null;
6150889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong
6160889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        FileInputStream is = null;
6170889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        try {
6180889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            FileDescriptor fd = null;
6190889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            File file = new File(path);
6200889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            if (file.exists()) {
6210889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong                is = new FileInputStream(file);
6220889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong                fd = is.getFD();
6230889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            }
6240889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            mime = _getOriginalMimeType(mUniqueId, path, fd);
6250889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        } catch (IOException ioe) {
6260889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        } finally {
6270889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            if (is != null) {
6280889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong                try {
6290889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong                    is.close();
6300889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong                } catch(IOException e) {}
6310889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong            }
6320889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        }
6330889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong
6340889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong        return mime;
635d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
636d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
637d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
6380e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the MIME type embedded in the original content.
639dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI of the rights-protected content.
6410e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6420e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return MIME type of the original content, such as <code>video/mpeg</code>.
643dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
644dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public String getOriginalMimeType(Uri uri) {
645dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
646dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
647dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
648dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return getOriginalMimeType(convertUriToPath(uri));
649dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
650dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
651dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6520e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given content has valid rights.
6530e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6540e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
655d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
6560e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
657d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
658d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int checkRightsStatus(String path) {
659d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return checkRightsStatus(path, DrmStore.Action.DEFAULT);
660d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
661d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
662d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
6630e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Check whether the given content has valid rights.
6640e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6650e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI of the rights-protected content.
666dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6670e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
668dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
669dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int checkRightsStatus(Uri uri) {
670dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
671dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
672dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
673dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return checkRightsStatus(convertUriToPath(uri));
674dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
675dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
676dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6770e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given rights-protected content has valid rights for the specified
6780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link DrmStore.Action}.
679d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
6800e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
6810e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action The {@link DrmStore.Action} to perform.
6820e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6830e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
684d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
685d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int checkRightsStatus(String path, int action) {
686d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
687d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given path or action is not valid");
688d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
689d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _checkRightsStatus(mUniqueId, path, action);
690d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
691d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
692d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
6930e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given rights-protected content has valid rights for the specified
6940e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link DrmStore.Action}.
6950e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6960e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the rights-protected content.
6970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action The {@link DrmStore.Action} to perform.
698dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6990e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
700dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
701dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int checkRightsStatus(Uri uri, int action) {
702dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
703dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
704dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
705dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return checkRightsStatus(convertUriToPath(uri), action);
706dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
707dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
708dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
7090e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Removes the rights associated with the given rights-protected content.
710d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7110e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
7120e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7130e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
714d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
715dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int removeRights(String path) {
716d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("")) {
717d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given path should be non null");
718d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
719dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return _removeRights(mUniqueId, path);
720dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
721dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
722dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
7230e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Removes the rights associated with the given rights-protected content.
7240e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7250e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the rights-protected content.
726dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
7270e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
728dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
729dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int removeRights(Uri uri) {
730dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
731dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
732dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
733dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return removeRights(convertUriToPath(uri));
734d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
735d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
736d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7370e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Removes all the rights information of every DRM plug-in (agent) associated with
7380e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the DRM framework. Will be used during a master reset.
739dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
7400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
741d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
742dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int removeAllRights() {
743dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int result = ERROR_UNKNOWN;
744dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != mEventHandler) {
745dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Message msg = mEventHandler.obtainMessage(ACTION_REMOVE_ALL_RIGHTS);
746dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
747dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
748dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return result;
749d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
750d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
751d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7520e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Initiates a new conversion session. An application must initiate a conversion session
7530e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * with this method each time it downloads a rights-protected file that needs to be converted.
7540e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *<p>
7550e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * This method applies only to forward-locking (copy protection) DRM schemes.
7560e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7570e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the input data packet.
758d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7590e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A convert ID that is used used to maintain the conversion session.
760d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
761d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int openConvertSession(String mimeType) {
762d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == mimeType || mimeType.equals("")) {
763d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Path or the mimeType should be non null");
764d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
765d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _openConvertSession(mUniqueId, mimeType);
766d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
767d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
768d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7690e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Converts the input data (content) that is part of a rights-protected file. The converted
7700e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * data and status is returned in a {@link DrmConvertedStatus} object. This method should be
7710e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * called each time there is a new block of data received by the application.
772d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7730e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param convertId Handle for the conversion session.
7740e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param inputData Input data that needs to be converted.
7750e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7760e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link DrmConvertedStatus} object that contains the status of the data conversion,
7770e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the converted data, and offset for the header and body signature. An application can
7780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * ignore the offset because it is only relevant to the
7790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #closeConvertSession closeConvertSession()} method.
780d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
781d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public DrmConvertedStatus convertData(int convertId, byte[] inputData) {
782d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == inputData || 0 >= inputData.length) {
783d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given inputData should be non null");
784d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
785d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _convertData(mUniqueId, convertId, inputData);
786d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
787d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
788d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7890e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Informs the DRM plug-in (agent) that there is no more data to convert or that an error
7900e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * has occurred. Upon successful conversion of the data, the DRM agent will provide an offset
7910e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * value indicating where the header and body signature should be added. Appending the
7920e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * signature is necessary to protect the integrity of the converted file.
7930e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7940e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param convertId Handle for the conversion session.
795d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7960e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link DrmConvertedStatus} object that contains the status of the data conversion,
7970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the converted data, and the offset for the header and body signature.
798d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
799d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public DrmConvertedStatus closeConvertSession(int convertId) {
800d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _closeConvertSession(mUniqueId, convertId);
801d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
802d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
803dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private int getEventType(int infoType) {
804dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int eventType = -1;
805dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
806dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        switch (infoType) {
807dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
808dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
809dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
810c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            eventType = DrmEvent.TYPE_DRM_INFO_PROCESSED;
811dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
812dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
813dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return eventType;
814dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
815dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
816dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private int getErrorType(int infoType) {
817dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int error = -1;
818dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
819dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        switch (infoType) {
820dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
821dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
822dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
823c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            error = DrmErrorEvent.TYPE_PROCESS_DRM_INFO_FAILED;
824dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
825dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
826dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return error;
827dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
828dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
829dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
830dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     * This method expects uri in the following format
831dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *     content://media/<table_name>/<row_index> (or)
832dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *     file://sdcard/test.mp4
833b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang     *     http://test.com/test.mp4
834dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
835dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     * Here <table_name> shall be "video" or "audio" or "images"
836dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     * <row_index> the index of the content in given table
837dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
838dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private String convertUriToPath(Uri uri) {
839c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        String path = null;
840f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi        if (null != uri) {
841f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            String scheme = uri.getScheme();
842f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            if (null == scheme || scheme.equals("") ||
843f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    scheme.equals(ContentResolver.SCHEME_FILE)) {
844f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                path = uri.getPath();
845b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang
846b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang            } else if (scheme.equals("http")) {
847b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang                path = uri.toString();
848b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang
849f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
850f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                String[] projection = new String[] {MediaStore.MediaColumns.DATA};
851f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                Cursor cursor = null;
852f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                try {
853f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    cursor = mContext.getContentResolver().query(uri, projection, null,
854f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                            null, null);
855f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
856f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                        throw new IllegalArgumentException("Given Uri could not be found" +
857f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                                " in media store");
858f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    }
859f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
860f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    path = cursor.getString(pathIndex);
861f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                } catch (SQLiteException e) {
862f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    throw new IllegalArgumentException("Given Uri is not formatted in a way " +
863f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                            "so that it can be found in media store.");
864f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                } finally {
865f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    if (null != cursor) {
866f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                        cursor.close();
867f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    }
868f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                }
869f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            } else {
870f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                throw new IllegalArgumentException("Given Uri scheme is not supported");
871c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            }
872dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
873dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return path;
874dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
875dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
876d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    // private native interfaces
8776225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private native int _initialize();
8786225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
8796225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private native void _setListeners(int uniqueId, Object weak_this);
880d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
8816225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private native void _release(int uniqueId);
882d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
883d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native void _installDrmEngine(int uniqueId, String engineFilepath);
884d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
885d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native ContentValues _getConstraints(int uniqueId, String path, int usage);
886d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
887dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    private native ContentValues _getMetadata(int uniqueId, String path);
888dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
889d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native boolean _canHandle(int uniqueId, String path, String mimeType);
890d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
891d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmInfoStatus _processDrmInfo(int uniqueId, DrmInfo drmInfo);
892d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
893d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmInfo _acquireDrmInfo(int uniqueId, DrmInfoRequest drmInfoRequest);
894d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
895dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native int _saveRights(
896d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, DrmRights drmRights, String rightsPath, String contentPath);
897d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
898d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native int _getDrmObjectType(int uniqueId, String path, String mimeType);
899d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
9000889fdae87abd9ec78a6c1d00c2771acfa4e4d34James Dong    private native String _getOriginalMimeType(int uniqueId, String path, FileDescriptor fd);
901d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
902d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native int _checkRightsStatus(int uniqueId, String path, int action);
903d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
904dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native int _removeRights(int uniqueId, String path);
905d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
906dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native int _removeAllRights(int uniqueId);
907d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
908d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native int _openConvertSession(int uniqueId, String mimeType);
909d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
910dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native DrmConvertedStatus _convertData(
911dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            int uniqueId, int convertId, byte[] inputData);
912d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
913d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmConvertedStatus _closeConvertSession(int uniqueId, int convertId);
914d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
915d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmSupportInfo[] _getAllSupportInfo(int uniqueId);
916011385508726fef027641fcbb3e4e446efc9af2cJames Dong
917011385508726fef027641fcbb3e4e446efc9af2cJames Dong    private void createEventThreads() {
918011385508726fef027641fcbb3e4e446efc9af2cJames Dong        if (mEventHandler == null && mInfoHandler == null) {
919011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mInfoThread = new HandlerThread("DrmManagerClient.InfoHandler");
920011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mInfoThread.start();
921011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mInfoHandler = new InfoHandler(mInfoThread.getLooper());
922011385508726fef027641fcbb3e4e446efc9af2cJames Dong
923011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mEventThread = new HandlerThread("DrmManagerClient.EventHandler");
924011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mEventThread.start();
925011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mEventHandler = new EventHandler(mEventThread.getLooper());
926011385508726fef027641fcbb3e4e446efc9af2cJames Dong        }
927011385508726fef027641fcbb3e4e446efc9af2cJames Dong    }
928011385508726fef027641fcbb3e4e446efc9af2cJames Dong
929011385508726fef027641fcbb3e4e446efc9af2cJames Dong    private void createListeners() {
930011385508726fef027641fcbb3e4e446efc9af2cJames Dong        _setListeners(mUniqueId, new WeakReference<DrmManagerClient>(this));
931011385508726fef027641fcbb3e4e446efc9af2cJames Dong    }
932d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
933d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
934