DrmManagerClient.java revision 011385508726fef027641fcbb3e4e446efc9af2c
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
32d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport java.io.IOException;
33d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport java.lang.ref.WeakReference;
34d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshiimport java.util.ArrayList;
35dc549d60f98d809f626c99de614960409a847054Takeshi Aimiimport java.util.HashMap;
36d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
37d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi/**
380e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber * The main programming interface for the DRM framework. An application must instantiate this class
390e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber * to access DRM agents through the DRM framework.
40d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi *
41d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi */
42d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshipublic class DrmManagerClient {
43dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
440e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Indicates that a request was successful or that no error occurred.
45dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
46dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public static final int ERROR_NONE = 0;
47dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
480e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Indicates that an error occurred and the reason is not known.
49dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
50dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public static final int ERROR_UNKNOWN = -2000;
51dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
526225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    HandlerThread mInfoThread;
536225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    HandlerThread mEventThread;
54dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private static final String TAG = "DrmManagerClient";
55d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
56d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    static {
57d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        // Load the respective library
58d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        System.loadLibrary("drmframework_jni");
59d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
60d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
61d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
620e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Interface definition for a callback that receives status messages and warnings
630e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * during registration and rights acquisition.
64d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
65d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public interface OnInfoListener {
66d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        /**
670e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * Called when the DRM framework sends status or warning information during registration
680e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * and rights acquisition.
69d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi         *
700e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param client The <code>DrmManagerClient</code> instance.
710e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param event The {@link DrmInfoEvent} instance that wraps the status information or
720e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * warnings.
73d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi         */
74d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        public void onInfo(DrmManagerClient client, DrmInfoEvent event);
75d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
76d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
77dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Interface definition for a callback that receives information
790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * about DRM processing events.
80dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
81dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public interface OnEventListener {
82dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        /**
830e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * Called when the DRM framework sends information about a DRM processing request.
84dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         *
850e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param client The <code>DrmManagerClient</code> instance.
860e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param event The {@link DrmEvent} instance that wraps the information being
870e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * conveyed, such as the information type and message.
88dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         */
89f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang        public void onEvent(DrmManagerClient client, DrmEvent event);
90dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
91dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
92dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
930e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Interface definition for a callback that receives information about DRM framework errors.
94dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
95dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public interface OnErrorListener {
96dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        /**
970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * Called when the DRM framework sends error information.
98dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         *
990e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param client The <code>DrmManagerClient</code> instance.
1000e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber         * @param event The {@link DrmErrorEvent} instance that wraps the error type and message.
101dc549d60f98d809f626c99de614960409a847054Takeshi Aimi         */
102dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public void onError(DrmManagerClient client, DrmErrorEvent event);
103dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
104dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
105c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    private static final int ACTION_REMOVE_ALL_RIGHTS = 1001;
106dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    private static final int ACTION_PROCESS_DRM_INFO = 1002;
107d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
108d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private int mUniqueId;
109d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private int mNativeContext;
1106225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private boolean mReleased;
111dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private Context mContext;
112dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private InfoHandler mInfoHandler;
113d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private EventHandler mEventHandler;
114d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private OnInfoListener mOnInfoListener;
115dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private OnEventListener mOnEventListener;
116dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private OnErrorListener mOnErrorListener;
117d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
118dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private class EventHandler extends Handler {
119dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
120dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public EventHandler(Looper looper) {
121dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            super(looper);
122dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
123dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
124dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public void handleMessage(Message msg) {
125dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            DrmEvent event = null;
126dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            DrmErrorEvent error = null;
127dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            HashMap<String, Object> attributes = new HashMap<String, Object>();
128dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
129dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            switch(msg.what) {
130dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            case ACTION_PROCESS_DRM_INFO: {
131dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                final DrmInfo drmInfo = (DrmInfo) msg.obj;
132dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                DrmInfoStatus status = _processDrmInfo(mUniqueId, drmInfo);
133f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang
134f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                attributes.put(DrmEvent.DRM_INFO_STATUS_OBJECT, status);
135f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                attributes.put(DrmEvent.DRM_INFO_OBJECT, drmInfo);
136f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang
137dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (null != status && DrmInfoStatus.STATUS_OK == status.statusCode) {
138f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                    event = new DrmEvent(mUniqueId,
139f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                            getEventType(status.infoType), null, attributes);
140dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                } else {
141c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi                    int infoType = (null != status) ? status.infoType : drmInfo.getInfoType();
142f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                    error = new DrmErrorEvent(mUniqueId,
143f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                            getErrorType(infoType), null, attributes);
144dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
145dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                break;
146dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
147dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            case ACTION_REMOVE_ALL_RIGHTS: {
148dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (ERROR_NONE == _removeAllRights(mUniqueId)) {
149dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_ALL_RIGHTS_REMOVED, null);
150dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                } else {
151dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    error = new DrmErrorEvent(mUniqueId,
152dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                            DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED, null);
153dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
154dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                break;
155dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
156dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            default:
157dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                Log.e(TAG, "Unknown message type " + msg.what);
158dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                return;
159dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
160dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            if (null != mOnEventListener && null != event) {
161f8bf3c46f524b1252bf466a351daaef61afdcecbGloria Wang                mOnEventListener.onEvent(DrmManagerClient.this, event);
162dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
163dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            if (null != mOnErrorListener && null != error) {
164dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                mOnErrorListener.onError(DrmManagerClient.this, error);
165dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            }
166dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
167dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
168dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
169d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
170d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     * {@hide}
171d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
172dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public static void notify(
173dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Object thisReference, int uniqueId, int infoType, String message) {
174d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmManagerClient instance = (DrmManagerClient)((WeakReference)thisReference).get();
175d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
176dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != instance && null != instance.mInfoHandler) {
177dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Message m = instance.mInfoHandler.obtainMessage(
178dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                InfoHandler.INFO_EVENT_TYPE, uniqueId, infoType, message);
179dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            instance.mInfoHandler.sendMessage(m);
180d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
181d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
182d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
183dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private class InfoHandler extends Handler {
184d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        public static final int INFO_EVENT_TYPE = 1;
185d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
186dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        public InfoHandler(Looper looper) {
187d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            super(looper);
188d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
189d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
190d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        public void handleMessage(Message msg) {
19127b277779c89251f2aafcc7a56db95d264900c9dGloria Wang            DrmInfoEvent info = null;
192dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            DrmErrorEvent error = null;
193d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
194d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            switch (msg.what) {
195dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            case InfoHandler.INFO_EVENT_TYPE:
196d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                int uniqueId = msg.arg1;
197d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                int infoType = msg.arg2;
198d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                String message = msg.obj.toString();
199d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
200dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                switch (infoType) {
201dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                case DrmInfoEvent.TYPE_REMOVE_RIGHTS: {
202d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    try {
203d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                        DrmUtils.removeFile(message);
204d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    } catch (IOException e) {
205d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                        e.printStackTrace();
206d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                    }
20727b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                    info = new DrmInfoEvent(uniqueId, infoType, message);
208dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
209dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
21027b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT:
21127b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_RIGHTS_INSTALLED:
21227b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_WAIT_FOR_RIGHTS:
21327b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_ACCOUNT_ALREADY_REGISTERED:
21427b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                case DrmInfoEvent.TYPE_RIGHTS_REMOVED: {
21527b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                    info = new DrmInfoEvent(uniqueId, infoType, message);
216dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
217dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
218dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                default:
219dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    error = new DrmErrorEvent(uniqueId, infoType, message);
220dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    break;
221d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                }
222d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
22327b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                if (null != mOnInfoListener && null != info) {
22427b277779c89251f2aafcc7a56db95d264900c9dGloria Wang                    mOnInfoListener.onInfo(DrmManagerClient.this, info);
225d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                }
226dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                if (null != mOnErrorListener && null != error) {
227dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                    mOnErrorListener.onError(DrmManagerClient.this, error);
228dc549d60f98d809f626c99de614960409a847054Takeshi Aimi                }
229d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                return;
230d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            default:
231d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                Log.e(TAG, "Unknown message type " + msg.what);
232d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                return;
233d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            }
234d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
235d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
236d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
237d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
2380e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Creates a <code>DrmManagerClient</code>.
239d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
2400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param context Context of the caller.
241d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
242d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public DrmManagerClient(Context context) {
243dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        mContext = context;
2446225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mReleased = false;
245011385508726fef027641fcbb3e4e446efc9af2cJames Dong        createEventThreads();
246dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
247d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        // save the unique id
2486225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mUniqueId = _initialize();
249c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    }
250c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi
251c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi    protected void finalize() {
2526225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        if (!mReleased) {
2536225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            Log.w(TAG, "You should have called release()");
2546225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            release();
2556225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        }
2566225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    }
2576225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
2586225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    /**
2596225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     * Releases resources associated with the current session of DrmManagerClient.
2606225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     *
2616225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     * It is considered good practice to call this method when the {@link DrmManagerClient} object
2626225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     * is no longer needed in your application. After release() is called,
2636225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     * {@link DrmManagerClient} is no longer usable since it has lost all of its required resource.
2646225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi     */
2656225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    public void release() {
2666225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        if (mReleased) {
2676225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            Log.w(TAG, "You have already called release()");
2686225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            return;
2696225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        }
2706225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mReleased = true;
2716225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        if (mEventHandler != null) {
2726225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            mEventThread.quit();
2736225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            mEventThread = null;
2746225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        }
2756225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        if (mInfoHandler != null) {
2766225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            mInfoThread.quit();
2776225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            mInfoThread = null;
2786225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        }
2796225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mEventHandler = null;
2806225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mInfoHandler = null;
2816225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnEventListener = null;
2826225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnInfoListener = null;
2836225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnErrorListener = null;
2846225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        _release(mUniqueId);
285d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
286d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
287d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
2880e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Registers an {@link DrmManagerClient.OnInfoListener} callback, which is invoked when the
2890e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * DRM framework sends status or warning information during registration or rights acquisition.
290d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
2910e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param infoListener Interface definition for the callback.
292d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
293dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public synchronized void setOnInfoListener(OnInfoListener infoListener) {
2946225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnInfoListener = infoListener;
295dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != infoListener) {
2966225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            createListeners();
297dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
298dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
299dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
300dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
3010e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Registers an {@link DrmManagerClient.OnEventListener} callback, which is invoked when the
3020e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * DRM framework sends information about DRM processing.
303dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
3040e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param eventListener Interface definition for the callback.
305dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
306dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public synchronized void setOnEventListener(OnEventListener eventListener) {
3076225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnEventListener = eventListener;
308dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != eventListener) {
3096225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            createListeners();
310dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
311dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
312dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
313dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
3140e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Registers an {@link DrmManagerClient.OnErrorListener} callback, which is invoked when
3150e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the DRM framework sends error information.
316dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
3170e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param errorListener Interface definition for the callback.
318dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
319dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public synchronized void setOnErrorListener(OnErrorListener errorListener) {
3206225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi        mOnErrorListener = errorListener;
321dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != errorListener) {
3226225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi            createListeners();
323d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
324d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
325d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
326d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
3270e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves information about all the DRM plug-ins (agents) that are registered with
3280e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the DRM framework.
329d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
3300e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A <code>String</code> array of DRM plug-in descriptions.
331d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
332d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public String[] getAvailableDrmEngines() {
333d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        DrmSupportInfo[] supportInfos = _getAllSupportInfo(mUniqueId);
334d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        ArrayList<String> descriptions = new ArrayList<String>();
335d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
336d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        for (int i = 0; i < supportInfos.length; i++) {
337d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            descriptions.add(supportInfos[i].getDescriprition());
338d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
339d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
340d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        String[] drmEngines = new String[descriptions.size()];
341d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return descriptions.toArray(drmEngines);
342d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
343d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
344d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
3450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves constraint information for rights-protected content.
346d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
3470e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the content from which you are retrieving DRM constraints.
3480e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action Action defined in {@link DrmStore.Action}.
3490e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
3500e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link android.content.ContentValues} instance that contains
3510e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * key-value pairs representing the constraints. Null in case of failure.
352365ce1db339db53cd5afb118ff867fe940644e45James Dong     * The keys are defined in {@link DrmStore.ConstraintsColumns}.
353d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
354d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public ContentValues getConstraints(String path, int action) {
355d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
356d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given usage or path is invalid/null");
357d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
358d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _getConstraints(mUniqueId, path, action);
359d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
360d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
361dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi   /**
3620e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * Retrieves metadata information for rights-protected content.
3630e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    *
3640e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @param path Path to the content from which you are retrieving metadata information.
365dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    *
3660e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @return A {@link android.content.ContentValues} instance that contains
3670e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * key-value pairs representing the metadata. Null in case of failure.
368dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    */
369dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public ContentValues getMetadata(String path) {
370dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        if (null == path || path.equals("")) {
371dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            throw new IllegalArgumentException("Given path is invalid/null");
372dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        }
373dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return _getMetadata(mUniqueId, path);
374dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
375dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
376d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
3770e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves constraint information for rights-protected content.
3780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
3790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the content from which you are retrieving DRM constraints.
3800e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action Action defined in {@link DrmStore.Action}.
381dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
3820e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link android.content.ContentValues} instance that contains
3830e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * key-value pairs representing the constraints. Null in case of failure.
384dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
385dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public ContentValues getConstraints(Uri uri, int action) {
386c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
387c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            throw new IllegalArgumentException("Uri should be non null");
388c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        }
389dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return getConstraints(convertUriToPath(uri), action);
390dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
391dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
392dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi   /**
3930e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * Retrieves metadata information for rights-protected content.
394dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    *
3950e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @param uri URI for the content from which you are retrieving metadata information.
3960e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    *
3970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * @return A {@link android.content.ContentValues} instance that contains
3980e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber    * key-value pairs representing the constraints. Null in case of failure.
399dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    */
400dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public ContentValues getMetadata(Uri uri) {
401dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
402dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi            throw new IllegalArgumentException("Uri should be non null");
403dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        }
404dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return getMetadata(convertUriToPath(uri));
405dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
406dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
407dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
4080e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Saves rights to a specified path and associates that path with the content path.
4090e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4100e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * <p class="note"><strong>Note:</strong> For OMA or WM-DRM, <code>rightsPath</code> and
4110e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * <code>contentPath</code> can be null.</p>
4120e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4130e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmRights The {@link DrmRights} to be saved.
4140e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param rightsPath File path where rights will be saved.
4150e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param contentPath File path where content is saved.
416d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
4170e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
418b01e10c5bc0a29d1b0da96783b6d1582baeb2af2Joe Onorato     *
4190e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @throws IOException If the call failed to save rights information at the given
4200e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * <code>rightsPath</code>.
421d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
422dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int saveRights(
423d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            DrmRights drmRights, String rightsPath, String contentPath) throws IOException {
424dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == drmRights || !drmRights.isValid()) {
425d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given drmRights or contentPath is not valid");
426d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
427d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null != rightsPath && !rightsPath.equals("")) {
428d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            DrmUtils.writeToFile(rightsPath, drmRights.getData());
429d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
430dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return _saveRights(mUniqueId, drmRights, rightsPath, contentPath);
431d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
432d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
433d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4340e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Installs a new DRM plug-in (agent) at runtime.
4350e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4360e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param engineFilePath File path to the plug-in file to be installed.
437d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
438d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     * {@hide}
439d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
440d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public void installDrmEngine(String engineFilePath) {
441d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == engineFilePath || engineFilePath.equals("")) {
442d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException(
443d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi                "Given engineFilePath: "+ engineFilePath + "is not valid");
444d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
445d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        _installDrmEngine(mUniqueId, engineFilePath);
446d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
447d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
448d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4490e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given MIME type or path can be handled.
4500e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4510e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path of the content to be handled.
4520e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the object to be handled.
453d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
4540e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return True if the given MIME type or path can be handled; false if they cannot be handled.
455d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
456d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public boolean canHandle(String path, String mimeType) {
457d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
458d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Path or the mimetype should be non null");
459d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
460d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _canHandle(mUniqueId, path, mimeType);
461d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
462d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
463d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4640e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given MIME type or URI can be handled.
4650e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
4660e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the content to be handled.
4670e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the object to be handled
468dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
4690e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return True if the given MIME type or URI can be handled; false if they cannot be handled.
470dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
471dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public boolean canHandle(Uri uri, String mimeType) {
472dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
473dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Uri or the mimetype should be non null");
474dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
475dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return canHandle(convertUriToPath(uri), mimeType);
476dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
477dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
478dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
4790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Processes the given DRM information based on the information type.
480d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
4810e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmInfo The {@link DrmInfo} to be processed.
4820e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
483d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
484dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int processDrmInfo(DrmInfo drmInfo) {
485d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == drmInfo || !drmInfo.isValid()) {
486d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given drmInfo is invalid/null");
487d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
488dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int result = ERROR_UNKNOWN;
489dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != mEventHandler) {
490dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Message msg = mEventHandler.obtainMessage(ACTION_PROCESS_DRM_INFO, drmInfo);
491dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
492dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
493dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return result;
494d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
495d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
496d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
4970e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves information for registering, unregistering, or acquiring rights.
498d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
4990e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmInfoRequest The {@link DrmInfoRequest} that specifies the type of DRM
5000e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * information being retrieved.
5010e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5020e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link DrmInfo} instance.
503d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
504dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public DrmInfo acquireDrmInfo(DrmInfoRequest drmInfoRequest) {
505d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == drmInfoRequest || !drmInfoRequest.isValid()) {
506d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given drmInfoRequest is invalid/null");
507d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
508dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return _acquireDrmInfo(mUniqueId, drmInfoRequest);
509dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    }
510dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
511dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    /**
5120e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Processes a given {@link DrmInfoRequest} and returns the rights information asynchronously.
5130e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *<p>
5140e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * This is a utility method that consists of an
5150e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #acquireDrmInfo(DrmInfoRequest) acquireDrmInfo()} and a
5160e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #processDrmInfo(DrmInfo) processDrmInfo()} method call. This utility method can be
5170e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * used only if the selected DRM plug-in (agent) supports this sequence of calls. Some DRM
5180e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * agents, such as OMA, do not support this utility method, in which case an application must
5190e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * invoke {@link #acquireDrmInfo(DrmInfoRequest) acquireDrmInfo()} and
5200e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #processDrmInfo(DrmInfo) processDrmInfo()} separately.
521dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi     *
5220e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param drmInfoRequest The {@link DrmInfoRequest} used to acquire the rights.
5230e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
524dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi     */
525dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    public int acquireRights(DrmInfoRequest drmInfoRequest) {
526dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        DrmInfo drmInfo = acquireDrmInfo(drmInfoRequest);
5274ef690a38b1dfdff3ae34e260435edcec37e520fGloria Wang        if (null == drmInfo) {
5284ef690a38b1dfdff3ae34e260435edcec37e520fGloria Wang            return ERROR_UNKNOWN;
5294ef690a38b1dfdff3ae34e260435edcec37e520fGloria Wang        }
530dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi        return processDrmInfo(drmInfo);
531d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
532d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
533d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
5340e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the type of rights-protected object (for example, content object, rights
5350e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * object, and so on) using the specified path or MIME type. At least one parameter must
5360e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * be specified to retrieve the DRM object type.
537d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
5380e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the content or null.
5390e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the content or null.
5400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5410e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> that corresponds to a {@link DrmStore.DrmObjectType}.
542d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
543d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int getDrmObjectType(String path, String mimeType) {
544d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
545d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Path or the mimetype should be non null");
546d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
547d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _getDrmObjectType(mUniqueId, path, mimeType);
548d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
549d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
550d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
5510e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the type of rights-protected object (for example, content object, rights
5520e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * object, and so on) using the specified URI or MIME type. At least one parameter must
5530e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * be specified to retrieve the DRM object type.
554dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
5550e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the content or null.
5560e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the content or null.
5570e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5580e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> that corresponds to a {@link DrmStore.DrmObjectType}.
559dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
560dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int getDrmObjectType(Uri uri, String mimeType) {
561dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
562dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Uri or the mimetype should be non null");
563dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
564dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        String path = "";
565dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        try {
566dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            path = convertUriToPath(uri);
567dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        } catch (Exception e) {
568dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            // Even uri is invalid the mimetype shall be valid, so allow to proceed further.
569dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Log.w(TAG, "Given Uri could not be found in media store");
570dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
571dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return getDrmObjectType(path, mimeType);
572dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
573dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
574dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
5750e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the MIME type embedded in the original content.
5760e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5770e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
578d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
5790e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return The MIME type of the original content, such as <code>video/mpeg</code>.
580d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
581d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public String getOriginalMimeType(String path) {
582d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("")) {
583d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given path should be non null");
584d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
585d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _getOriginalMimeType(mUniqueId, path);
586d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
587d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
588d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
5890e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Retrieves the MIME type embedded in the original content.
590dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
5910e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI of the rights-protected content.
5920e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
5930e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return MIME type of the original content, such as <code>video/mpeg</code>.
594dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
595dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public String getOriginalMimeType(Uri uri) {
596dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
597dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
598dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
599dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return getOriginalMimeType(convertUriToPath(uri));
600dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
601dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
602dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6030e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given content has valid rights.
6040e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6050e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
606d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
6070e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
608d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
609d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int checkRightsStatus(String path) {
610d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return checkRightsStatus(path, DrmStore.Action.DEFAULT);
611d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
612d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
613d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
6140e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Check whether the given content has valid rights.
6150e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6160e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI of the rights-protected content.
617dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6180e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
619dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
620dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int checkRightsStatus(Uri uri) {
621dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
622dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
623dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
624dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return checkRightsStatus(convertUriToPath(uri));
625dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
626dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
627dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6280e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given rights-protected content has valid rights for the specified
6290e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link DrmStore.Action}.
630d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
6310e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
6320e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action The {@link DrmStore.Action} to perform.
6330e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6340e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
635d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
636d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int checkRightsStatus(String path, int action) {
637d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
638d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given path or action is not valid");
639d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
640d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _checkRightsStatus(mUniqueId, path, action);
641d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
642d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
643d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
6440e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Checks whether the given rights-protected content has valid rights for the specified
6450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link DrmStore.Action}.
6460e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6470e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the rights-protected content.
6480e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param action The {@link DrmStore.Action} to perform.
649dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6500e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return An <code>int</code> representing the {@link DrmStore.RightsStatus} of the content.
651dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
652dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int checkRightsStatus(Uri uri, int action) {
653dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
654dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
655dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
656dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return checkRightsStatus(convertUriToPath(uri), action);
657dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
658dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
659dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6600e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Removes the rights associated with the given rights-protected content.
661d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
6620e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param path Path to the rights-protected content.
6630e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6640e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
665d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
666dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int removeRights(String path) {
667d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == path || path.equals("")) {
668d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given path should be non null");
669d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
670dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return _removeRights(mUniqueId, path);
671dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
672dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
673dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
6740e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Removes the rights associated with the given rights-protected content.
6750e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
6760e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param uri URI for the rights-protected content.
677dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6780e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
679dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
680dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int removeRights(Uri uri) {
681dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null == uri || Uri.EMPTY == uri) {
682dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            throw new IllegalArgumentException("Given uri is not valid");
683dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
684dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return removeRights(convertUriToPath(uri));
685d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
686d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
687d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
6880e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Removes all the rights information of every DRM plug-in (agent) associated with
6890e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the DRM framework. Will be used during a master reset.
690dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
6910e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
692d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
693dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    public int removeAllRights() {
694dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int result = ERROR_UNKNOWN;
695dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        if (null != mEventHandler) {
696dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            Message msg = mEventHandler.obtainMessage(ACTION_REMOVE_ALL_RIGHTS);
697dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
698dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
699dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return result;
700d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
701d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
702d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7030e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Initiates a new conversion session. An application must initiate a conversion session
7040e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * with this method each time it downloads a rights-protected file that needs to be converted.
7050e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *<p>
7060e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * This method applies only to forward-locking (copy protection) DRM schemes.
7070e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7080e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param mimeType MIME type of the input data packet.
709d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7100e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A convert ID that is used used to maintain the conversion session.
711d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
712d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public int openConvertSession(String mimeType) {
713d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == mimeType || mimeType.equals("")) {
714d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Path or the mimeType should be non null");
715d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
716d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _openConvertSession(mUniqueId, mimeType);
717d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
718d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
719d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7200e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Converts the input data (content) that is part of a rights-protected file. The converted
7210e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * data and status is returned in a {@link DrmConvertedStatus} object. This method should be
7220e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * called each time there is a new block of data received by the application.
723d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7240e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param convertId Handle for the conversion session.
7250e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param inputData Input data that needs to be converted.
7260e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7270e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link DrmConvertedStatus} object that contains the status of the data conversion,
7280e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the converted data, and offset for the header and body signature. An application can
7290e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * ignore the offset because it is only relevant to the
7300e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * {@link #closeConvertSession closeConvertSession()} method.
731d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
732d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public DrmConvertedStatus convertData(int convertId, byte[] inputData) {
733d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        if (null == inputData || 0 >= inputData.length) {
734d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            throw new IllegalArgumentException("Given inputData should be non null");
735d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        }
736d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _convertData(mUniqueId, convertId, inputData);
737d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
738d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
739d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    /**
7400e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * Informs the DRM plug-in (agent) that there is no more data to convert or that an error
7410e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * has occurred. Upon successful conversion of the data, the DRM agent will provide an offset
7420e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * value indicating where the header and body signature should be added. Appending the
7430e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * signature is necessary to protect the integrity of the converted file.
7440e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     *
7450e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @param convertId Handle for the conversion session.
746d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     *
7470e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * @return A {@link DrmConvertedStatus} object that contains the status of the data conversion,
7480e092f806b0a4b81785a52da8ba22d2d47087de5Bill Gruber     * the converted data, and the offset for the header and body signature.
749d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi     */
750d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    public DrmConvertedStatus closeConvertSession(int convertId) {
751d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi        return _closeConvertSession(mUniqueId, convertId);
752d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    }
753d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
754dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private int getEventType(int infoType) {
755dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int eventType = -1;
756dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
757dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        switch (infoType) {
758dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
759dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
760dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
761c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            eventType = DrmEvent.TYPE_DRM_INFO_PROCESSED;
762dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
763dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
764dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return eventType;
765dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
766dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
767dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private int getErrorType(int infoType) {
768dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        int error = -1;
769dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
770dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        switch (infoType) {
771dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
772dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
773dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
774c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            error = DrmErrorEvent.TYPE_PROCESS_DRM_INFO_FAILED;
775dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            break;
776dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
777dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return error;
778dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
779dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
780dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    /**
781dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     * This method expects uri in the following format
782dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *     content://media/<table_name>/<row_index> (or)
783dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *     file://sdcard/test.mp4
784b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang     *     http://test.com/test.mp4
785dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     *
786dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     * Here <table_name> shall be "video" or "audio" or "images"
787dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     * <row_index> the index of the content in given table
788dc549d60f98d809f626c99de614960409a847054Takeshi Aimi     */
789dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private String convertUriToPath(Uri uri) {
790c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi        String path = null;
791f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi        if (null != uri) {
792f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            String scheme = uri.getScheme();
793f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            if (null == scheme || scheme.equals("") ||
794f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    scheme.equals(ContentResolver.SCHEME_FILE)) {
795f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                path = uri.getPath();
796b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang
797b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang            } else if (scheme.equals("http")) {
798b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang                path = uri.toString();
799b8b6a9a8d405d2a3f1d593ebaf7f07574dd586b9Gloria Wang
800f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
801f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                String[] projection = new String[] {MediaStore.MediaColumns.DATA};
802f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                Cursor cursor = null;
803f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                try {
804f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    cursor = mContext.getContentResolver().query(uri, projection, null,
805f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                            null, null);
806f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
807f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                        throw new IllegalArgumentException("Given Uri could not be found" +
808f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                                " in media store");
809f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    }
810f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
811f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    path = cursor.getString(pathIndex);
812f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                } catch (SQLiteException e) {
813f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    throw new IllegalArgumentException("Given Uri is not formatted in a way " +
814f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                            "so that it can be found in media store.");
815f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                } finally {
816f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    if (null != cursor) {
817f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                        cursor.close();
818f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                    }
819f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                }
820f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi            } else {
821f05913aaa0cc96eab32be3431de1a80d405527a1Takeshi Aimi                throw new IllegalArgumentException("Given Uri scheme is not supported");
822c7b3ccc564448cb4b918728421f9402bc18278c5Takeshi Aimi            }
823dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        }
824dc549d60f98d809f626c99de614960409a847054Takeshi Aimi        return path;
825dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    }
826dc549d60f98d809f626c99de614960409a847054Takeshi Aimi
827d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    // private native interfaces
8286225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private native int _initialize();
8296225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi
8306225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private native void _setListeners(int uniqueId, Object weak_this);
831d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
8326225df010365d00b1d0f3b1ca13f18cea537c8e3Kei Takahashi    private native void _release(int uniqueId);
833d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
834d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native void _installDrmEngine(int uniqueId, String engineFilepath);
835d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
836d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native ContentValues _getConstraints(int uniqueId, String path, int usage);
837d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
838dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi    private native ContentValues _getMetadata(int uniqueId, String path);
839dc91865622e3cc9ff0bb33b83f1d3b38cd7a6d7aTakeshi Aimi
840d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native boolean _canHandle(int uniqueId, String path, String mimeType);
841d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
842d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmInfoStatus _processDrmInfo(int uniqueId, DrmInfo drmInfo);
843d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
844d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmInfo _acquireDrmInfo(int uniqueId, DrmInfoRequest drmInfoRequest);
845d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
846dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native int _saveRights(
847d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi            int uniqueId, DrmRights drmRights, String rightsPath, String contentPath);
848d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
849d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native int _getDrmObjectType(int uniqueId, String path, String mimeType);
850d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
851d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native String _getOriginalMimeType(int uniqueId, String path);
852d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
853d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native int _checkRightsStatus(int uniqueId, String path, int action);
854d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
855dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native int _removeRights(int uniqueId, String path);
856d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
857dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native int _removeAllRights(int uniqueId);
858d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
859d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native int _openConvertSession(int uniqueId, String mimeType);
860d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
861dc549d60f98d809f626c99de614960409a847054Takeshi Aimi    private native DrmConvertedStatus _convertData(
862dc549d60f98d809f626c99de614960409a847054Takeshi Aimi            int uniqueId, int convertId, byte[] inputData);
863d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
864d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmConvertedStatus _closeConvertSession(int uniqueId, int convertId);
865d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
866d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi    private native DrmSupportInfo[] _getAllSupportInfo(int uniqueId);
867011385508726fef027641fcbb3e4e446efc9af2cJames Dong
868011385508726fef027641fcbb3e4e446efc9af2cJames Dong    private void createEventThreads() {
869011385508726fef027641fcbb3e4e446efc9af2cJames Dong        if (mEventHandler == null && mInfoHandler == null) {
870011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mInfoThread = new HandlerThread("DrmManagerClient.InfoHandler");
871011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mInfoThread.start();
872011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mInfoHandler = new InfoHandler(mInfoThread.getLooper());
873011385508726fef027641fcbb3e4e446efc9af2cJames Dong
874011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mEventThread = new HandlerThread("DrmManagerClient.EventHandler");
875011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mEventThread.start();
876011385508726fef027641fcbb3e4e446efc9af2cJames Dong            mEventHandler = new EventHandler(mEventThread.getLooper());
877011385508726fef027641fcbb3e4e446efc9af2cJames Dong        }
878011385508726fef027641fcbb3e4e446efc9af2cJames Dong    }
879011385508726fef027641fcbb3e4e446efc9af2cJames Dong
880011385508726fef027641fcbb3e4e446efc9af2cJames Dong    private void createListeners() {
881011385508726fef027641fcbb3e4e446efc9af2cJames Dong        _setListeners(mUniqueId, new WeakReference<DrmManagerClient>(this));
882011385508726fef027641fcbb3e4e446efc9af2cJames Dong    }
883d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi}
884d074e30ce44b9e33da43b67a4515b8986ca72b26aimitakeshi
885