DrmManagerClient.java revision f8bf3c46f524b1252bf466a351daaef61afdcecb
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.drm;
18
19import android.content.ContentResolver;
20import android.content.ContentValues;
21import android.content.Context;
22import android.database.Cursor;
23import android.database.sqlite.SQLiteException;
24import android.net.Uri;
25import android.os.Handler;
26import android.os.HandlerThread;
27import android.os.Looper;
28import android.os.Message;
29import android.provider.MediaStore;
30import android.util.Log;
31
32import java.io.IOException;
33import java.lang.ref.WeakReference;
34import java.util.ArrayList;
35import java.util.HashMap;
36
37/**
38 * Interface of DRM Framework.
39 * Java application will instantiate this class
40 * to access DRM agent through DRM Framework.
41 *
42 */
43public class DrmManagerClient {
44    /**
45     * Constant field signifies the success or no error occurred
46     */
47    public static final int ERROR_NONE = 0;
48    /**
49     * Constant field signifies that error occurred and the reason is not known
50     */
51    public static final int ERROR_UNKNOWN = -2000;
52
53    private static final String TAG = "DrmManagerClient";
54
55    static {
56        // Load the respective library
57        System.loadLibrary("drmframework_jni");
58    }
59
60    /**
61     * Interface definition of a callback to be invoked to communicate
62     * some info and/or warning about DrmManagerClient.
63     */
64    public interface OnInfoListener {
65        /**
66         * Called to indicate an info or a warning.
67         *
68         * @param client DrmManagerClient instance
69         * @param event instance which wraps reason and necessary information
70         */
71        public void onInfo(DrmManagerClient client, DrmInfoEvent event);
72    }
73
74    /**
75     * Interface definition of a callback to be invoked to communicate
76     * the result of time consuming APIs asynchronously
77     */
78    public interface OnEventListener {
79        /**
80         * Called to indicate the result of asynchronous APIs.
81         *
82         * @param client DrmManagerClient instance
83         * @param event instance which wraps type and message
84         */
85        public void onEvent(DrmManagerClient client, DrmEvent event);
86    }
87
88    /**
89     * Interface definition of a callback to be invoked to communicate
90     * the error occurred
91     */
92    public interface OnErrorListener {
93        /**
94         * Called to indicate the error occurred.
95         *
96         * @param client DrmManagerClient instance
97         * @param event instance which wraps error type and message
98         */
99        public void onError(DrmManagerClient client, DrmErrorEvent event);
100    }
101
102    private static final int ACTION_REMOVE_ALL_RIGHTS = 1001;
103    private static final int ACTION_PROCESS_DRM_INFO = 1002;
104
105    private int mUniqueId;
106    private int mNativeContext;
107    private Context mContext;
108    private InfoHandler mInfoHandler;
109    private EventHandler mEventHandler;
110    private OnInfoListener mOnInfoListener;
111    private OnEventListener mOnEventListener;
112    private OnErrorListener mOnErrorListener;
113
114    private class EventHandler extends Handler {
115
116        public EventHandler(Looper looper) {
117            super(looper);
118        }
119
120        public void handleMessage(Message msg) {
121            DrmEvent event = null;
122            DrmErrorEvent error = null;
123            HashMap<String, Object> attributes = new HashMap<String, Object>();
124
125            switch(msg.what) {
126            case ACTION_PROCESS_DRM_INFO: {
127                final DrmInfo drmInfo = (DrmInfo) msg.obj;
128                DrmInfoStatus status = _processDrmInfo(mUniqueId, drmInfo);
129
130                attributes.put(DrmEvent.DRM_INFO_STATUS_OBJECT, status);
131                attributes.put(DrmEvent.DRM_INFO_OBJECT, drmInfo);
132
133                if (null != status && DrmInfoStatus.STATUS_OK == status.statusCode) {
134                    event = new DrmEvent(mUniqueId,
135                            getEventType(status.infoType), null, attributes);
136                } else {
137                    int infoType = (null != status) ? status.infoType : drmInfo.getInfoType();
138                    error = new DrmErrorEvent(mUniqueId,
139                            getErrorType(infoType), null, attributes);
140                }
141                break;
142            }
143            case ACTION_REMOVE_ALL_RIGHTS: {
144                if (ERROR_NONE == _removeAllRights(mUniqueId)) {
145                    event = new DrmEvent(mUniqueId, DrmEvent.TYPE_ALL_RIGHTS_REMOVED, null);
146                } else {
147                    error = new DrmErrorEvent(mUniqueId,
148                            DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED, null);
149                }
150                break;
151            }
152            default:
153                Log.e(TAG, "Unknown message type " + msg.what);
154                return;
155            }
156            if (null != mOnEventListener && null != event) {
157                mOnEventListener.onEvent(DrmManagerClient.this, event);
158            }
159            if (null != mOnErrorListener && null != error) {
160                mOnErrorListener.onError(DrmManagerClient.this, error);
161            }
162        }
163    }
164
165    /**
166     * {@hide}
167     */
168    public static void notify(
169            Object thisReference, int uniqueId, int infoType, String message) {
170        DrmManagerClient instance = (DrmManagerClient)((WeakReference)thisReference).get();
171
172        if (null != instance && null != instance.mInfoHandler) {
173            Message m = instance.mInfoHandler.obtainMessage(
174                InfoHandler.INFO_EVENT_TYPE, uniqueId, infoType, message);
175            instance.mInfoHandler.sendMessage(m);
176        }
177    }
178
179    private class InfoHandler extends Handler {
180        public static final int INFO_EVENT_TYPE = 1;
181
182        public InfoHandler(Looper looper) {
183            super(looper);
184        }
185
186        public void handleMessage(Message msg) {
187            DrmInfoEvent info = null;
188            DrmErrorEvent error = null;
189
190            switch (msg.what) {
191            case InfoHandler.INFO_EVENT_TYPE:
192                int uniqueId = msg.arg1;
193                int infoType = msg.arg2;
194                String message = msg.obj.toString();
195
196                switch (infoType) {
197                case DrmInfoEvent.TYPE_REMOVE_RIGHTS: {
198                    try {
199                        DrmUtils.removeFile(message);
200                    } catch (IOException e) {
201                        e.printStackTrace();
202                    }
203                    info = new DrmInfoEvent(uniqueId, infoType, message);
204                    break;
205                }
206                case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT:
207                case DrmInfoEvent.TYPE_RIGHTS_INSTALLED:
208                case DrmInfoEvent.TYPE_WAIT_FOR_RIGHTS:
209                case DrmInfoEvent.TYPE_ACCOUNT_ALREADY_REGISTERED:
210                case DrmInfoEvent.TYPE_RIGHTS_REMOVED: {
211                    info = new DrmInfoEvent(uniqueId, infoType, message);
212                    break;
213                }
214                default:
215                    error = new DrmErrorEvent(uniqueId, infoType, message);
216                    break;
217                }
218
219                if (null != mOnInfoListener && null != info) {
220                    mOnInfoListener.onInfo(DrmManagerClient.this, info);
221                }
222                if (null != mOnErrorListener && null != error) {
223                    mOnErrorListener.onError(DrmManagerClient.this, error);
224                }
225                return;
226            default:
227                Log.e(TAG, "Unknown message type " + msg.what);
228                return;
229            }
230        }
231    }
232
233    /**
234     * To instantiate DrmManagerClient
235     *
236     * @param context context of the caller
237     */
238    public DrmManagerClient(Context context) {
239        mContext = context;
240
241        HandlerThread infoThread = new HandlerThread("DrmManagerClient.InfoHandler");
242        infoThread.start();
243        mInfoHandler = new InfoHandler(infoThread.getLooper());
244
245        HandlerThread eventThread = new HandlerThread("DrmManagerClient.EventHandler");
246        eventThread.start();
247        mEventHandler = new EventHandler(eventThread.getLooper());
248
249        // save the unique id
250        mUniqueId = hashCode();
251
252        _initialize(mUniqueId, new WeakReference<DrmManagerClient>(this));
253    }
254
255    protected void finalize() {
256        _finalize(mUniqueId);
257    }
258
259    /**
260     * Register a callback to be invoked when the caller required to receive
261     * supplementary information.
262     *
263     * @param infoListener
264     */
265    public synchronized void setOnInfoListener(OnInfoListener infoListener) {
266        if (null != infoListener) {
267            mOnInfoListener = infoListener;
268        }
269    }
270
271    /**
272     * Register a callback to be invoked when the caller required to receive
273     * the result of asynchronous APIs.
274     *
275     * @param eventListener
276     */
277    public synchronized void setOnEventListener(OnEventListener eventListener) {
278        if (null != eventListener) {
279            mOnEventListener = eventListener;
280        }
281    }
282
283    /**
284     * Register a callback to be invoked when the caller required to receive
285     * error result of asynchronous APIs.
286     *
287     * @param errorListener
288     */
289    public synchronized void setOnErrorListener(OnErrorListener errorListener) {
290        if (null != errorListener) {
291            mOnErrorListener = errorListener;
292        }
293    }
294
295    /**
296     * Retrieves informations about all the plug-ins registered with DrmFramework.
297     *
298     * @return Array of DrmEngine plug-in strings
299     */
300    public String[] getAvailableDrmEngines() {
301        DrmSupportInfo[] supportInfos = _getAllSupportInfo(mUniqueId);
302        ArrayList<String> descriptions = new ArrayList<String>();
303
304        for (int i = 0; i < supportInfos.length; i++) {
305            descriptions.add(supportInfos[i].getDescriprition());
306        }
307
308        String[] drmEngines = new String[descriptions.size()];
309        return descriptions.toArray(drmEngines);
310    }
311
312    /**
313     * Get constraints information evaluated from DRM content
314     *
315     * @param path Content path from where DRM constraints would be retrieved.
316     * @param action Actions defined in {@link DrmStore.Action}
317     * @return ContentValues instance in which constraints key-value pairs are embedded
318     *         or null in case of failure
319     */
320    public ContentValues getConstraints(String path, int action) {
321        if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
322            throw new IllegalArgumentException("Given usage or path is invalid/null");
323        }
324        return _getConstraints(mUniqueId, path, action);
325    }
326
327   /**
328    * Get metadata information from DRM content
329    *
330    * @param path Content path from where DRM metadata would be retrieved.
331    * @return ContentValues instance in which metadata key-value pairs are embedded
332    *         or null in case of failure
333    */
334    public ContentValues getMetadata(String path) {
335        if (null == path || path.equals("")) {
336            throw new IllegalArgumentException("Given path is invalid/null");
337        }
338        return _getMetadata(mUniqueId, path);
339    }
340
341    /**
342     * Get constraints information evaluated from DRM content
343     *
344     * @param uri Content URI from where DRM constraints would be retrieved.
345     * @param action Actions defined in {@link DrmStore.Action}
346     * @return ContentValues instance in which constraints key-value pairs are embedded
347     *         or null in case of failure
348     */
349    public ContentValues getConstraints(Uri uri, int action) {
350        if (null == uri || Uri.EMPTY == uri) {
351            throw new IllegalArgumentException("Uri should be non null");
352        }
353        return getConstraints(convertUriToPath(uri), action);
354    }
355
356   /**
357    * Get metadata information from DRM content
358    *
359    * @param uri Content URI from where DRM metadata would be retrieved.
360    * @return ContentValues instance in which metadata key-value pairs are embedded
361    *         or null in case of failure
362    */
363    public ContentValues getMetadata(Uri uri) {
364        if (null == uri || Uri.EMPTY == uri) {
365            throw new IllegalArgumentException("Uri should be non null");
366        }
367        return getMetadata(convertUriToPath(uri));
368    }
369
370    /**
371     * Save DRM rights to specified rights path
372     * and make association with content path.
373     *
374     * <p class="note">In case of OMA or WM-DRM, rightsPath and contentPath could be null.</p>
375     *
376     * @param drmRights DrmRights to be saved
377     * @param rightsPath File path where rights to be saved
378     * @param contentPath File path where content was saved
379     * @return
380     *     ERROR_NONE for success
381     *     ERROR_UNKNOWN for failure
382     * @throws IOException if failed to save rights information in the given path
383     */
384    public int saveRights(
385            DrmRights drmRights, String rightsPath, String contentPath) throws IOException {
386        if (null == drmRights || !drmRights.isValid()) {
387            throw new IllegalArgumentException("Given drmRights or contentPath is not valid");
388        }
389        if (null != rightsPath && !rightsPath.equals("")) {
390            DrmUtils.writeToFile(rightsPath, drmRights.getData());
391        }
392        return _saveRights(mUniqueId, drmRights, rightsPath, contentPath);
393    }
394
395    /**
396     * Install new DRM Engine Plug-in at the runtime
397     *
398     * @param engineFilePath Path of the plug-in file to be installed
399     * {@hide}
400     */
401    public void installDrmEngine(String engineFilePath) {
402        if (null == engineFilePath || engineFilePath.equals("")) {
403            throw new IllegalArgumentException(
404                "Given engineFilePath: "+ engineFilePath + "is not valid");
405        }
406        _installDrmEngine(mUniqueId, engineFilePath);
407    }
408
409    /**
410     * Check whether the given mimetype or path can be handled.
411     *
412     * @param path Path of the content to be handled
413     * @param mimeType Mimetype of the object to be handled
414     * @return
415     *        true - if the given mimeType or path can be handled
416     *        false - cannot be handled.
417     */
418    public boolean canHandle(String path, String mimeType) {
419        if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
420            throw new IllegalArgumentException("Path or the mimetype should be non null");
421        }
422        return _canHandle(mUniqueId, path, mimeType);
423    }
424
425    /**
426     * Check whether the given mimetype or uri can be handled.
427     *
428     * @param uri Content URI of the data to be handled.
429     * @param mimeType Mimetype of the object to be handled
430     * @return
431     *        true - if the given mimeType or path can be handled
432     *        false - cannot be handled.
433     */
434    public boolean canHandle(Uri uri, String mimeType) {
435        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
436            throw new IllegalArgumentException("Uri or the mimetype should be non null");
437        }
438        return canHandle(convertUriToPath(uri), mimeType);
439    }
440
441    /**
442     * Executes given drm information based on its type
443     *
444     * @param drmInfo Information needs to be processed
445     * @return
446     *     ERROR_NONE for success
447     *     ERROR_UNKNOWN for failure
448     */
449    public int processDrmInfo(DrmInfo drmInfo) {
450        if (null == drmInfo || !drmInfo.isValid()) {
451            throw new IllegalArgumentException("Given drmInfo is invalid/null");
452        }
453        int result = ERROR_UNKNOWN;
454        if (null != mEventHandler) {
455            Message msg = mEventHandler.obtainMessage(ACTION_PROCESS_DRM_INFO, drmInfo);
456            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
457        }
458        return result;
459    }
460
461    /**
462     * Retrieves necessary information for register, unregister or rights acquisition.
463     *
464     * @param drmInfoRequest Request information to retrieve drmInfo
465     * @return DrmInfo Instance as a result of processing given input
466     */
467    public DrmInfo acquireDrmInfo(DrmInfoRequest drmInfoRequest) {
468        if (null == drmInfoRequest || !drmInfoRequest.isValid()) {
469            throw new IllegalArgumentException("Given drmInfoRequest is invalid/null");
470        }
471        return _acquireDrmInfo(mUniqueId, drmInfoRequest);
472    }
473
474    /**
475     * Executes given DrmInfoRequest and returns the rights information asynchronously.
476     * This is a utility API which consists of {@link #acquireDrmInfo(DrmInfoRequest)}
477     * and {@link #processDrmInfo(DrmInfo)}.
478     * It can be used if selected DRM agent can work with this combined sequences.
479     * In case of some DRM schemes, such as OMA DRM, application needs to invoke
480     * {@link #acquireDrmInfo(DrmInfoRequest)} and {@link #processDrmInfo(DrmInfo)}, separately.
481     *
482     * @param drmInfoRequest Request information to retrieve drmInfo
483     * @return
484     *     ERROR_NONE for success
485     *     ERROR_UNKNOWN for failure
486     */
487    public int acquireRights(DrmInfoRequest drmInfoRequest) {
488        DrmInfo drmInfo = acquireDrmInfo(drmInfoRequest);
489        if (null == drmInfo) {
490            return ERROR_UNKNOWN;
491        }
492        return processDrmInfo(drmInfo);
493    }
494
495    /**
496     * Retrieves the type of the protected object (content, rights, etc..)
497     * using specified path or mimetype. At least one parameter should be non null
498     * to retrieve DRM object type
499     *
500     * @param path Path of the content or null.
501     * @param mimeType Mimetype of the content or null.
502     * @return Type of the DRM content.
503     * @see DrmStore.DrmObjectType
504     */
505    public int getDrmObjectType(String path, String mimeType) {
506        if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) {
507            throw new IllegalArgumentException("Path or the mimetype should be non null");
508        }
509        return _getDrmObjectType(mUniqueId, path, mimeType);
510    }
511
512    /**
513     * Retrieves the type of the protected object (content, rights, etc..)
514     * using specified uri or mimetype. At least one parameter should be non null
515     * to retrieve DRM object type
516     *
517     * @param uri The content URI of the data
518     * @param mimeType Mimetype of the content or null.
519     * @return Type of the DRM content.
520     * @see DrmStore.DrmObjectType
521     */
522    public int getDrmObjectType(Uri uri, String mimeType) {
523        if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) {
524            throw new IllegalArgumentException("Uri or the mimetype should be non null");
525        }
526        String path = "";
527        try {
528            path = convertUriToPath(uri);
529        } catch (Exception e) {
530            // Even uri is invalid the mimetype shall be valid, so allow to proceed further.
531            Log.w(TAG, "Given Uri could not be found in media store");
532        }
533        return getDrmObjectType(path, mimeType);
534    }
535
536    /**
537     * Retrieves the mime type embedded inside the original content
538     *
539     * @param path Path of the protected content
540     * @return Mimetype of the original content, such as "video/mpeg"
541     */
542    public String getOriginalMimeType(String path) {
543        if (null == path || path.equals("")) {
544            throw new IllegalArgumentException("Given path should be non null");
545        }
546        return _getOriginalMimeType(mUniqueId, path);
547    }
548
549    /**
550     * Retrieves the mime type embedded inside the original content
551     *
552     * @param uri The content URI of the data
553     * @return Mimetype of the original content, such as "video/mpeg"
554     */
555    public String getOriginalMimeType(Uri uri) {
556        if (null == uri || Uri.EMPTY == uri) {
557            throw new IllegalArgumentException("Given uri is not valid");
558        }
559        return getOriginalMimeType(convertUriToPath(uri));
560    }
561
562    /**
563     * Check whether the given content has valid rights or not
564     *
565     * @param path Path of the protected content
566     * @return Status of the rights for the protected content
567     * @see DrmStore.RightsStatus
568     */
569    public int checkRightsStatus(String path) {
570        return checkRightsStatus(path, DrmStore.Action.DEFAULT);
571    }
572
573    /**
574     * Check whether the given content has valid rights or not
575     *
576     * @param uri The content URI of the data
577     * @return Status of the rights for the protected content
578     * @see DrmStore.RightsStatus
579     */
580    public int checkRightsStatus(Uri uri) {
581        if (null == uri || Uri.EMPTY == uri) {
582            throw new IllegalArgumentException("Given uri is not valid");
583        }
584        return checkRightsStatus(convertUriToPath(uri));
585    }
586
587    /**
588     * Check whether the given content has valid rights or not for specified action.
589     *
590     * @param path Path of the protected content
591     * @param action Action to perform
592     * @return Status of the rights for the protected content
593     * @see DrmStore.RightsStatus
594     */
595    public int checkRightsStatus(String path, int action) {
596        if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
597            throw new IllegalArgumentException("Given path or action is not valid");
598        }
599        return _checkRightsStatus(mUniqueId, path, action);
600    }
601
602    /**
603     * Check whether the given content has valid rights or not for specified action.
604     *
605     * @param uri The content URI of the data
606     * @param action Action to perform
607     * @return Status of the rights for the protected content
608     * @see DrmStore.RightsStatus
609     */
610    public int checkRightsStatus(Uri uri, int action) {
611        if (null == uri || Uri.EMPTY == uri) {
612            throw new IllegalArgumentException("Given uri is not valid");
613        }
614        return checkRightsStatus(convertUriToPath(uri), action);
615    }
616
617    /**
618     * Removes the rights associated with the given protected content
619     *
620     * @param path Path of the protected content
621     * @return
622     *     ERROR_NONE for success
623     *     ERROR_UNKNOWN for failure
624     */
625    public int removeRights(String path) {
626        if (null == path || path.equals("")) {
627            throw new IllegalArgumentException("Given path should be non null");
628        }
629        return _removeRights(mUniqueId, path);
630    }
631
632    /**
633     * Removes the rights associated with the given protected content
634     *
635     * @param uri The content URI of the data
636     * @return
637     *     ERROR_NONE for success
638     *     ERROR_UNKNOWN for failure
639     */
640    public int removeRights(Uri uri) {
641        if (null == uri || Uri.EMPTY == uri) {
642            throw new IllegalArgumentException("Given uri is not valid");
643        }
644        return removeRights(convertUriToPath(uri));
645    }
646
647    /**
648     * Removes all the rights information of every plug-in associated with
649     * DRM framework. Will be used in master reset
650     *
651     * @return
652     *     ERROR_NONE for success
653     *     ERROR_UNKNOWN for failure
654     */
655    public int removeAllRights() {
656        int result = ERROR_UNKNOWN;
657        if (null != mEventHandler) {
658            Message msg = mEventHandler.obtainMessage(ACTION_REMOVE_ALL_RIGHTS);
659            result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result;
660        }
661        return result;
662    }
663
664    /**
665     * This API is for Forward Lock based DRM scheme.
666     * Each time the application tries to download a new DRM file
667     * which needs to be converted, then the application has to
668     * begin with calling this API.
669     *
670     * @param mimeType Description/MIME type of the input data packet
671     * @return convert ID which will be used for maintaining convert session.
672     */
673    public int openConvertSession(String mimeType) {
674        if (null == mimeType || mimeType.equals("")) {
675            throw new IllegalArgumentException("Path or the mimeType should be non null");
676        }
677        return _openConvertSession(mUniqueId, mimeType);
678    }
679
680    /**
681     * Accepts and converts the input data which is part of DRM file.
682     * The resultant converted data and the status is returned in the DrmConvertedInfo
683     * object. This method will be called each time there are new block
684     * of data received by the application.
685     *
686     * @param convertId Handle for the convert session
687     * @param inputData Input Data which need to be converted
688     * @return Return object contains the status of the data conversion,
689     *         the output converted data and offset. In this case the
690     *         application will ignore the offset information.
691     */
692    public DrmConvertedStatus convertData(int convertId, byte[] inputData) {
693        if (null == inputData || 0 >= inputData.length) {
694            throw new IllegalArgumentException("Given inputData should be non null");
695        }
696        return _convertData(mUniqueId, convertId, inputData);
697    }
698
699    /**
700     * Informs the Drm Agent when there is no more data which need to be converted
701     * or when an error occurs. Upon successful conversion of the complete data,
702     * the agent will inform that where the header and body signature
703     * should be added. This signature appending is needed to integrity
704     * protect the converted file.
705     *
706     * @param convertId Handle for the convert session
707     * @return Return object contains the status of the data conversion,
708     *     the header and body signature data. It also informs
709     *     the application on which offset these signature data should be appended.
710     */
711    public DrmConvertedStatus closeConvertSession(int convertId) {
712        return _closeConvertSession(mUniqueId, convertId);
713    }
714
715    private int getEventType(int infoType) {
716        int eventType = -1;
717
718        switch (infoType) {
719        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
720        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
721        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
722            eventType = DrmEvent.TYPE_DRM_INFO_PROCESSED;
723            break;
724        }
725        return eventType;
726    }
727
728    private int getErrorType(int infoType) {
729        int error = -1;
730
731        switch (infoType) {
732        case DrmInfoRequest.TYPE_REGISTRATION_INFO:
733        case DrmInfoRequest.TYPE_UNREGISTRATION_INFO:
734        case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO:
735            error = DrmErrorEvent.TYPE_PROCESS_DRM_INFO_FAILED;
736            break;
737        }
738        return error;
739    }
740
741    /**
742     * This method expects uri in the following format
743     *     content://media/<table_name>/<row_index> (or)
744     *     file://sdcard/test.mp4
745     *     http://test.com/test.mp4
746     *
747     * Here <table_name> shall be "video" or "audio" or "images"
748     * <row_index> the index of the content in given table
749     */
750    private String convertUriToPath(Uri uri) {
751        String path = null;
752        if (null != uri) {
753            String scheme = uri.getScheme();
754            if (null == scheme || scheme.equals("") ||
755                    scheme.equals(ContentResolver.SCHEME_FILE)) {
756                path = uri.getPath();
757
758            } else if (scheme.equals("http")) {
759                path = uri.toString();
760
761            } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) {
762                String[] projection = new String[] {MediaStore.MediaColumns.DATA};
763                Cursor cursor = null;
764                try {
765                    cursor = mContext.getContentResolver().query(uri, projection, null,
766                            null, null);
767                    if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) {
768                        throw new IllegalArgumentException("Given Uri could not be found" +
769                                " in media store");
770                    }
771                    int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
772                    path = cursor.getString(pathIndex);
773                } catch (SQLiteException e) {
774                    throw new IllegalArgumentException("Given Uri is not formatted in a way " +
775                            "so that it can be found in media store.");
776                } finally {
777                    if (null != cursor) {
778                        cursor.close();
779                    }
780                }
781            } else {
782                throw new IllegalArgumentException("Given Uri scheme is not supported");
783            }
784        }
785        return path;
786    }
787
788    // private native interfaces
789    private native void _initialize(int uniqueId, Object weak_this);
790
791    private native void _finalize(int uniqueId);
792
793    private native void _installDrmEngine(int uniqueId, String engineFilepath);
794
795    private native ContentValues _getConstraints(int uniqueId, String path, int usage);
796
797    private native ContentValues _getMetadata(int uniqueId, String path);
798
799    private native boolean _canHandle(int uniqueId, String path, String mimeType);
800
801    private native DrmInfoStatus _processDrmInfo(int uniqueId, DrmInfo drmInfo);
802
803    private native DrmInfo _acquireDrmInfo(int uniqueId, DrmInfoRequest drmInfoRequest);
804
805    private native int _saveRights(
806            int uniqueId, DrmRights drmRights, String rightsPath, String contentPath);
807
808    private native int _getDrmObjectType(int uniqueId, String path, String mimeType);
809
810    private native String _getOriginalMimeType(int uniqueId, String path);
811
812    private native int _checkRightsStatus(int uniqueId, String path, int action);
813
814    private native int _removeRights(int uniqueId, String path);
815
816    private native int _removeAllRights(int uniqueId);
817
818    private native int _openConvertSession(int uniqueId, String mimeType);
819
820    private native DrmConvertedStatus _convertData(
821            int uniqueId, int convertId, byte[] inputData);
822
823    private native DrmConvertedStatus _closeConvertSession(int uniqueId, int convertId);
824
825    private native DrmSupportInfo[] _getAllSupportInfo(int uniqueId);
826}
827
828