diff options
author | Takeshi Aimi <aimitakeshi@gmail.com> | 2010-09-20 23:40:41 +0900 |
---|---|---|
committer | Takeshi Aimi <aimitakeshi@gmail.com> | 2010-10-04 22:14:53 +0900 |
commit | dc549d60f98d809f626c99de614960409a847054 (patch) | |
tree | bb40a8371811f1c591cc22afa331e57b3d091c9e /drm/java | |
parent | 7d9c73fb6f6f79f7f92b77482a0edbd7b89f2564 (diff) | |
download | frameworks_base-dc549d60f98d809f626c99de614960409a847054.zip frameworks_base-dc549d60f98d809f626c99de614960409a847054.tar.gz frameworks_base-dc549d60f98d809f626c99de614960409a847054.tar.bz2 |
Update of DRM framework.
- Change "void" type of return value to "int" for returning status.
- Add some of overloaded Java APIs which accept database Uri as input.
- Add asynchronous APIs
- Add OnEventListener and OnErrorListener for asynchronous APIs
- Disable debug log
- Change decrypt() API to accept an optional buffer needed by some of DRM schemes
Changes are incorporated by Sony Corporation.
Change-Id: I414a165e22cc79be6ea7cd28041788aa2b6b8f7c
Diffstat (limited to 'drm/java')
-rw-r--r-- | drm/java/android/drm/DrmErrorEvent.java | 89 | ||||
-rw-r--r-- | drm/java/android/drm/DrmEvent.java | 34 | ||||
-rw-r--r-- | drm/java/android/drm/DrmInfoEvent.java | 31 | ||||
-rw-r--r-- | drm/java/android/drm/DrmManagerClient.java | 530 |
4 files changed, 590 insertions, 94 deletions
diff --git a/drm/java/android/drm/DrmErrorEvent.java b/drm/java/android/drm/DrmErrorEvent.java new file mode 100644 index 0000000..8e71634 --- /dev/null +++ b/drm/java/android/drm/DrmErrorEvent.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.drm; + +/** + * This is an entity class which would be passed to caller in + * {@link DrmManagerClient.OnErrorListener#onError(DrmManagerClient, DrmErrorEvent)} + * + */ +public class DrmErrorEvent extends DrmEvent { + /** + * TYPE_RIGHTS_NOT_INSTALLED, when something went wrong installing the rights. + */ + public static final int TYPE_RIGHTS_NOT_INSTALLED = 2001; + /** + * TYPE_RIGHTS_RENEWAL_NOT_ALLOWED, when the server rejects renewal of rights. + */ + public static final int TYPE_RIGHTS_RENEWAL_NOT_ALLOWED = 2002; + /** + * TYPE_NOT_SUPPORTED, when answer from server can not be handled by the native agent. + */ + public static final int TYPE_NOT_SUPPORTED = 2003; + /** + * TYPE_OUT_OF_MEMORY, when memory allocation fail during renewal. + * Can in the future perhaps be used to trigger garbage collector. + */ + public static final int TYPE_OUT_OF_MEMORY = 2004; + /** + * TYPE_NO_INTERNET_CONNECTION, when the Internet connection is missing and no attempt + * can be made to renew rights. + */ + public static final int TYPE_NO_INTERNET_CONNECTION = 2005; + /** + * TYPE_REGISTRATION_FAILED, when failed to register with the service. + */ + public static final int TYPE_REGISTRATION_FAILED = 2006; + /** + * TYPE_UNREGISTRATION_FAILED, when failed to unregister with the service. + */ + public static final int TYPE_UNREGISTRATION_FAILED = 2007; + /** + * TYPE_RIGHTS_ACQUISITION_FAILED, when failed to acquire the rights information required. + */ + public static final int TYPE_RIGHTS_ACQUISITION_FAILED = 2008; + /** + * TYPE_INITIALIZE_FAILED, when failed to load and initialize the available plugins. + */ + public static final int TYPE_INITIALIZE_FAILED = 2009; + /** + * TYPE_FINALIZE_FAILED, when failed to unload and finalize the loaded plugins. + */ + public static final int TYPE_FINALIZE_FAILED = 2010; + /** + * TYPE_REMOVE_ALL_RIGHTS_FAILED, when failed to remove all the rights objects + * associated with all DRM schemes. + */ + public static final int TYPE_REMOVE_ALL_RIGHTS_FAILED = 2011; + /** + * TYPE_DRM_INFO_ACQUISITION_FAILED, when failed to get the required information to + * communicate with the service. + */ + public static final int TYPE_DRM_INFO_ACQUISITION_FAILED = 2012; + + /** + * constructor to create DrmErrorEvent object with given parameters + * + * @param uniqueId Unique session identifier + * @param type Type of information + * @param message Message description + */ + public DrmErrorEvent(int uniqueId, int type, String message) { + super(uniqueId, type, message); + } +} + diff --git a/drm/java/android/drm/DrmEvent.java b/drm/java/android/drm/DrmEvent.java index 44c4b43..d6e0c3a 100644 --- a/drm/java/android/drm/DrmEvent.java +++ b/drm/java/android/drm/DrmEvent.java @@ -22,6 +22,40 @@ package android.drm; * */ public class DrmEvent { + /** + * Constant field signifies that unload and finalize the loaded plugins successfully + */ + public static final int TYPE_FINALIZED = 1001; + /** + * Constant field signifies that register with the service successfully + */ + public static final int TYPE_REGISTERED = 1002; + /** + * Constant field signifies that load and initialized the available plugins successfully + */ + public static final int TYPE_INITIALIZED = 1003; + /** + * Constant field signifies that unregister with the service successfully + */ + public static final int TYPE_UNREGISTERED = 1004; + /** + * Constant field signifies that rights information is acquired successfully + */ + public static final int TYPE_RIGHTS_ACQUIRED = 1005; + /** + * Constant field signifies that all the rights information associated with + * all DRM schemes are removed successfully + */ + public static final int TYPE_ALL_RIGHTS_REMOVED = 1006; + /** + * Constant field signifies that the required information to communicate with + * the service is acquired sucessfully + */ + public static final int TYPE_DRM_INFO_ACQUIRED = 1007; + + public static final String DRM_INFO_STATUS_OBJECT = "drm_info_status_object"; + public static final String DRM_INFO_OBJECT = "drm_info_object"; + private final int mUniqueId; private final int mType; private String mMessage = ""; diff --git a/drm/java/android/drm/DrmInfoEvent.java b/drm/java/android/drm/DrmInfoEvent.java index be1b009..a778e06 100644 --- a/drm/java/android/drm/DrmInfoEvent.java +++ b/drm/java/android/drm/DrmInfoEvent.java @@ -26,42 +26,25 @@ public class DrmInfoEvent extends DrmEvent { * TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT, when registration has been already done * by another account ID. */ - public static final int TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT = 0x0000001; + public static final int TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT = 1; /** * TYPE_REMOVE_RIGHTS, when the rights needs to be removed completely. */ - public static final int TYPE_REMOVE_RIGHTS = 0x0000002; + public static final int TYPE_REMOVE_RIGHTS = 2; /** * TYPE_RIGHTS_INSTALLED, when the rights are downloaded and installed ok. */ - public static final int TYPE_RIGHTS_INSTALLED = 0x0000003; - /** - * TYPE_RIGHTS_NOT_INSTALLED, when something went wrong installing the rights. - */ - public static final int TYPE_RIGHTS_NOT_INSTALLED = 0x0000004; - /** - * TYPE_RIGHTS_RENEWAL_NOT_ALLOWED, when the server rejects renewal of rights. - */ - public static final int TYPE_RIGHTS_RENEWAL_NOT_ALLOWED = 0x0000005; - /** - * TYPE_NOT_SUPPORTED, when answer from server can not be handled by the native agent. - */ - public static final int TYPE_NOT_SUPPORTED = 0x0000006; + public static final int TYPE_RIGHTS_INSTALLED = 3; /** * TYPE_WAIT_FOR_RIGHTS, rights object is on it's way to phone, * wait before calling checkRights again. */ - public static final int TYPE_WAIT_FOR_RIGHTS = 0x0000007; - /** - * TYPE_OUT_OF_MEMORY, when memory allocation fail during renewal. - * Can in the future perhaps be used to trigger garbage collector. - */ - public static final int TYPE_OUT_OF_MEMORY = 0x0000008; + public static final int TYPE_WAIT_FOR_RIGHTS = 4; /** - * TYPE_NO_INTERNET_CONNECTION, when the Internet connection is missing and no attempt - * can be made to renew rights. + * TYPE_ACCOUNT_ALREADY_REGISTERED, when registration has been + * already done for the given account. */ - public static final int TYPE_NO_INTERNET_CONNECTION = 0x0000009; + public static final int TYPE_ACCOUNT_ALREADY_REGISTERED = 5; /** * constructor to create DrmInfoEvent object with given parameters diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java index 7ec70da..147c530 100644 --- a/drm/java/android/drm/DrmManagerClient.java +++ b/drm/java/android/drm/DrmManagerClient.java @@ -18,14 +18,19 @@ package android.drm; import android.content.ContentValues; import android.content.Context; +import android.database.Cursor; +import android.net.Uri; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; import android.os.Message; +import android.provider.MediaStore; import android.util.Log; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.HashMap; /** * Interface of DRM Framework. @@ -34,7 +39,16 @@ import java.util.ArrayList; * */ public class DrmManagerClient { - private static final String TAG = "DrmManager"; + /** + * Constant field signifies the success or no error occurred + */ + public static final int ERROR_NONE = 0; + /** + * Constant field signifies that error occurred and the reason is not known + */ + public static final int ERROR_UNKNOWN = -2000; + + private static final String TAG = "DrmManagerClient"; static { // Load the respective library @@ -55,55 +69,189 @@ public class DrmManagerClient { public void onInfo(DrmManagerClient client, DrmInfoEvent event); } - private static final int STATE_UNINITIALIZED = 0x00000000; - private static final int STATE_INITIALIZED = 0x00000001; + /** + * Interface definition of a callback to be invoked to communicate + * the result of time consuming APIs asynchronously + */ + public interface OnEventListener { + /** + * Called to indicate the result of asynchronous APIs. + * + * @param client DrmManagerClient instance + * @param event instance which wraps type and message + * @param attributes resultant values in key and value pair. + */ + public void onEvent(DrmManagerClient client, DrmEvent event, + HashMap<String, Object> attributes); + } + + /** + * Interface definition of a callback to be invoked to communicate + * the error occurred + */ + public interface OnErrorListener { + /** + * Called to indicate the error occurred. + * + * @param client DrmManagerClient instance + * @param event instance which wraps error type and message + */ + public void onError(DrmManagerClient client, DrmErrorEvent event); + } + + private static final int STATE_UNINITIALIZED = 0; + private static final int STATE_INITIALIZED = 1; + + private static final int ACTION_INITIALIZE = 1000; + private static final int ACTION_FINALIZE = 1001; + private static final int ACTION_REMOVE_ALL_RIGHTS = 1002; + private static final int ACTION_ACQUIRE_DRM_INFO = 1003; + private static final int ACTION_PROCESS_DRM_INFO = 1004; private int mUniqueId; private int mNativeContext; + private Context mContext; + private InfoHandler mInfoHandler; private EventHandler mEventHandler; private OnInfoListener mOnInfoListener; + private OnEventListener mOnEventListener; + private OnErrorListener mOnErrorListener; private int mCurrentState = STATE_UNINITIALIZED; + private class EventHandler extends Handler { + + public EventHandler(Looper looper) { + super(looper); + } + + public void handleMessage(Message msg) { + DrmEvent event = null; + DrmErrorEvent error = null; + HashMap<String, Object> attributes = new HashMap<String, Object>(); + + switch(msg.what) { + case ACTION_INITIALIZE: { + if (ERROR_NONE == _loadPlugIns(mUniqueId, msg.obj)) { + mCurrentState = STATE_INITIALIZED; + event = new DrmEvent(mUniqueId, DrmEvent.TYPE_INITIALIZED, null); + } else { + error = new DrmErrorEvent(mUniqueId, + DrmErrorEvent.TYPE_INITIALIZE_FAILED, null); + } + break; + } + case ACTION_ACQUIRE_DRM_INFO: { + final DrmInfoRequest request = (DrmInfoRequest) msg.obj; + DrmInfo drmInfo = _acquireDrmInfo(mUniqueId, request); + if (null != drmInfo) { + attributes.put(DrmEvent.DRM_INFO_OBJECT, drmInfo); + event = new DrmEvent(mUniqueId, DrmEvent.TYPE_DRM_INFO_ACQUIRED, null); + } else { + error = new DrmErrorEvent(mUniqueId, + DrmErrorEvent.TYPE_DRM_INFO_ACQUISITION_FAILED, null); + } + break; + } + case ACTION_PROCESS_DRM_INFO: { + final DrmInfo drmInfo = (DrmInfo) msg.obj; + DrmInfoStatus status = _processDrmInfo(mUniqueId, drmInfo); + if (null != status && DrmInfoStatus.STATUS_OK == status.statusCode) { + attributes.put(DrmEvent.DRM_INFO_STATUS_OBJECT, status); + event = new DrmEvent(mUniqueId, getEventType(drmInfo.getInfoType()), null); + } else { + error = new DrmErrorEvent(mUniqueId, + getErrorType(drmInfo.getInfoType()), null); + } + break; + } + case ACTION_REMOVE_ALL_RIGHTS: { + if (ERROR_NONE == _removeAllRights(mUniqueId)) { + event = new DrmEvent(mUniqueId, DrmEvent.TYPE_ALL_RIGHTS_REMOVED, null); + } else { + error = new DrmErrorEvent(mUniqueId, + DrmErrorEvent.TYPE_REMOVE_ALL_RIGHTS_FAILED, null); + } + break; + } + case ACTION_FINALIZE: { + if (ERROR_NONE == _unloadPlugIns(mUniqueId)) { + mCurrentState = STATE_UNINITIALIZED; + event = new DrmEvent(mUniqueId, DrmEvent.TYPE_FINALIZED, null); + } else { + error = new DrmErrorEvent(mUniqueId, + DrmErrorEvent.TYPE_FINALIZE_FAILED, null); + } + break; + } + default: + Log.e(TAG, "Unknown message type " + msg.what); + return; + } + if (null != mOnEventListener && null != event) { + mOnEventListener.onEvent(DrmManagerClient.this, event, attributes); + } + if (null != mOnErrorListener && null != error) { + mOnErrorListener.onError(DrmManagerClient.this, error); + } + } + } + /** * {@hide} */ - public static void notify(Object thisReference, int uniqueId, int infoType, String message) { + public static void notify( + Object thisReference, int uniqueId, int infoType, String message) { DrmManagerClient instance = (DrmManagerClient)((WeakReference)thisReference).get(); - if (null != instance && null != instance.mEventHandler) { - Message m = instance.mEventHandler.obtainMessage( - EventHandler.INFO_EVENT_TYPE, uniqueId, infoType, message); - instance.mEventHandler.sendMessage(m); + if (null != instance && null != instance.mInfoHandler) { + Message m = instance.mInfoHandler.obtainMessage( + InfoHandler.INFO_EVENT_TYPE, uniqueId, infoType, message); + instance.mInfoHandler.sendMessage(m); } } - private class EventHandler extends Handler { + private class InfoHandler extends Handler { public static final int INFO_EVENT_TYPE = 1; - public EventHandler(Looper looper) { + public InfoHandler(Looper looper) { super(looper); } public void handleMessage(Message msg) { + DrmInfoEvent event = null; + DrmErrorEvent error = null; switch (msg.what) { - case EventHandler.INFO_EVENT_TYPE: + case InfoHandler.INFO_EVENT_TYPE: int uniqueId = msg.arg1; int infoType = msg.arg2; String message = msg.obj.toString(); - if (infoType == DrmInfoEvent.TYPE_REMOVE_RIGHTS) { + switch (infoType) { + case DrmInfoEvent.TYPE_REMOVE_RIGHTS: { try { DrmUtils.removeFile(message); } catch (IOException e) { e.printStackTrace(); } + event = new DrmInfoEvent(uniqueId, infoType, message); + break; + } + case DrmInfoEvent.TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT: { + event = new DrmInfoEvent(uniqueId, infoType, message); + break; + } + default: + error = new DrmErrorEvent(uniqueId, infoType, message); + break; } - if (null != mOnInfoListener) { - DrmInfoEvent event = new DrmInfoEvent(uniqueId, infoType, message); + if (null != mOnInfoListener && null != event) { mOnInfoListener.onInfo(DrmManagerClient.this, event); } + if (null != mOnErrorListener && null != error) { + mOnErrorListener.onError(DrmManagerClient.this, error); + } return; default: Log.e(TAG, "Unknown message type " + msg.what); @@ -118,31 +266,58 @@ public class DrmManagerClient { * @param context context of the caller */ public DrmManagerClient(Context context) { + mContext = context; Looper looper; if (null != (looper = Looper.myLooper())) { - mEventHandler = new EventHandler(looper); + mInfoHandler = new InfoHandler(looper); } else if (null != (looper = Looper.getMainLooper())) { - mEventHandler = new EventHandler(looper); + mInfoHandler = new InfoHandler(looper); } else { - mEventHandler = null; + mInfoHandler = null; } + HandlerThread thread = new HandlerThread("DrmManagerClient.EventHandler"); + thread.start(); + mEventHandler = new EventHandler(thread.getLooper()); + // save the unique id mUniqueId = hashCode(); } /** * Register a callback to be invoked when the caller required to receive - * necessary information + * supplementary information. * * @param infoListener */ - public void setOnInfoListener(OnInfoListener infoListener) { - synchronized(this) { - if (null != infoListener) { - mOnInfoListener = infoListener; - } + public synchronized void setOnInfoListener(OnInfoListener infoListener) { + if (null != infoListener) { + mOnInfoListener = infoListener; + } + } + + /** + * Register a callback to be invoked when the caller required to receive + * the result of asynchronous APIs. + * + * @param eventListener + */ + public synchronized void setOnEventListener(OnEventListener eventListener) { + if (null != eventListener) { + mOnEventListener = eventListener; + } + } + + /** + * Register a callback to be invoked when the caller required to receive + * error result of asynchronous APIs. + * + * @param errorListener + */ + public synchronized void setOnErrorListener(OnErrorListener errorListener) { + if (null != errorListener) { + mOnErrorListener = errorListener; } } @@ -150,25 +325,43 @@ public class DrmManagerClient { * Initializes DrmFramework, which loads all available plug-ins * in the default plug-in directory path * + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure */ - public void loadPlugIns() { - if (getState() == STATE_UNINITIALIZED) { - _loadPlugIns(mUniqueId, new WeakReference<DrmManagerClient>(this)); - - mCurrentState = STATE_INITIALIZED; + public int loadPlugIns() { + int result = ERROR_UNKNOWN; + if (STATE_UNINITIALIZED == getState()) { + if (null != mEventHandler) { + Message msg = mEventHandler.obtainMessage( + ACTION_INITIALIZE, new WeakReference<DrmManagerClient>(this)); + result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result; + } + } else { + result = ERROR_NONE; } + return result; } /** * Finalize DrmFramework, which release resources associated with each plug-in * and unload all plug-ins. + * + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure */ - public void unloadPlugIns() { - if (getState() == STATE_INITIALIZED) { - _unloadPlugIns(mUniqueId); - - mCurrentState = STATE_UNINITIALIZED; + public int unloadPlugIns() { + int result = ERROR_UNKNOWN; + if (STATE_INITIALIZED == getState()) { + if (null != mEventHandler) { + Message msg = mEventHandler.obtainMessage(ACTION_FINALIZE); + result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result; + } + } else { + result = ERROR_NONE; } + return result; } /** @@ -177,7 +370,7 @@ public class DrmManagerClient { * @return Array of DrmEngine plug-in strings */ public String[] getAvailableDrmEngines() { - if (getState() == STATE_UNINITIALIZED) { + if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } @@ -203,13 +396,25 @@ public class DrmManagerClient { public ContentValues getConstraints(String path, int action) { if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) { throw new IllegalArgumentException("Given usage or path is invalid/null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _getConstraints(mUniqueId, path, action); } /** + * Get constraints information evaluated from DRM content + * + * @param uri The Content URI of the data + * @param action Actions defined in {@link DrmStore.Action} + * @return ContentValues instance in which constraints key-value pairs are embedded + * or null in case of failure + */ + public ContentValues getConstraints(Uri uri, int action) { + return getConstraints(convertUriToPath(uri), action); + } + + /** * Save DRM rights to specified rights path * and make association with content path. * @@ -218,20 +423,22 @@ public class DrmManagerClient { * @param drmRights DrmRights to be saved * @param rightsPath File path where rights to be saved * @param contentPath File path where content was saved + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure * @throws IOException if failed to save rights information in the given path */ - public void saveRights( + public int saveRights( DrmRights drmRights, String rightsPath, String contentPath) throws IOException { - if (null == drmRights || !drmRights.isValid() - || null == contentPath || contentPath.equals("")) { + if (null == drmRights || !drmRights.isValid()) { throw new IllegalArgumentException("Given drmRights or contentPath is not valid"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } if (null != rightsPath && !rightsPath.equals("")) { DrmUtils.writeToFile(rightsPath, drmRights.getData()); } - _saveRights(mUniqueId, drmRights, rightsPath, contentPath); + return _saveRights(mUniqueId, drmRights, rightsPath, contentPath); } /** @@ -244,7 +451,7 @@ public class DrmManagerClient { if (null == engineFilePath || engineFilePath.equals("")) { throw new IllegalArgumentException( "Given engineFilePath: "+ engineFilePath + "is not valid"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } _installDrmEngine(mUniqueId, engineFilePath); @@ -256,47 +463,78 @@ public class DrmManagerClient { * @param path Path of the content to be handled * @param mimeType Mimetype of the object to be handled * @return - * true - if the given mimeType or path can be handled. - * false - cannot be handled. false will be returned in case + * true - if the given mimeType or path can be handled + * false - cannot be handled. false will be return in case * the state is uninitialized */ public boolean canHandle(String path, String mimeType) { if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) { throw new IllegalArgumentException("Path or the mimetype should be non null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _canHandle(mUniqueId, path, mimeType); } /** + * Check whether the given mimetype or uri can be handled. + * + * @param uri The content URI of the data + * @param mimeType Mimetype of the object to be handled + * @return + * true - if the given mimeType or path can be handled + * false - cannot be handled. false will be return in case + * the state is uninitialized + */ + public boolean canHandle(Uri uri, String mimeType) { + if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) { + throw new IllegalArgumentException("Uri or the mimetype should be non null"); + } + return canHandle(convertUriToPath(uri), mimeType); + } + + /** * Executes given drm information based on its type * * @param drmInfo Information needs to be processed - * @return DrmInfoStatus Instance as a result of processing given input + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure */ - public DrmInfoStatus processDrmInfo(DrmInfo drmInfo) { + public int processDrmInfo(DrmInfo drmInfo) { if (null == drmInfo || !drmInfo.isValid()) { throw new IllegalArgumentException("Given drmInfo is invalid/null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } - return _processDrmInfo(mUniqueId, drmInfo); + int result = ERROR_UNKNOWN; + if (null != mEventHandler) { + Message msg = mEventHandler.obtainMessage(ACTION_PROCESS_DRM_INFO, drmInfo); + result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result; + } + return result; } /** * Retrieves necessary information for register, unregister or rights acquisition. * * @param drmInfoRequest Request information to retrieve drmInfo - * @return DrmInfo Instance as a result of processing given input + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure */ - public DrmInfo acquireDrmInfo(DrmInfoRequest drmInfoRequest) { + public int acquireDrmInfo(DrmInfoRequest drmInfoRequest) { if (null == drmInfoRequest || !drmInfoRequest.isValid()) { throw new IllegalArgumentException("Given drmInfoRequest is invalid/null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } - return _acquireDrmInfo(mUniqueId, drmInfoRequest); + int result = ERROR_UNKNOWN; + if (null != mEventHandler) { + Message msg = mEventHandler.obtainMessage(ACTION_ACQUIRE_DRM_INFO, drmInfoRequest); + result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result; + } + return result; } /** @@ -312,13 +550,37 @@ public class DrmManagerClient { public int getDrmObjectType(String path, String mimeType) { if ((null == path || path.equals("")) && (null == mimeType || mimeType.equals(""))) { throw new IllegalArgumentException("Path or the mimetype should be non null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _getDrmObjectType(mUniqueId, path, mimeType); } /** + * Retrieves the type of the protected object (content, rights, etc..) + * using specified uri or mimetype. At least one parameter should be non null + * to retrieve DRM object type + * + * @param uri The content URI of the data + * @param mimeType Mimetype of the content or null. + * @return Type of the DRM content. + * @see DrmStore.DrmObjectType + */ + public int getDrmObjectType(Uri uri, String mimeType) { + if ((null == uri || Uri.EMPTY == uri) && (null == mimeType || mimeType.equals(""))) { + throw new IllegalArgumentException("Uri or the mimetype should be non null"); + } + String path = ""; + try { + path = convertUriToPath(uri); + } catch (Exception e) { + // Even uri is invalid the mimetype shall be valid, so allow to proceed further. + Log.w(TAG, "Given Uri could not be found in media store"); + } + return getDrmObjectType(path, mimeType); + } + + /** * Retrieves the mime type embedded inside the original content * * @param path Path of the protected content @@ -327,13 +589,26 @@ public class DrmManagerClient { public String getOriginalMimeType(String path) { if (null == path || path.equals("")) { throw new IllegalArgumentException("Given path should be non null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _getOriginalMimeType(mUniqueId, path); } /** + * Retrieves the mime type embedded inside the original content + * + * @param uri The content URI of the data + * @return Mimetype of the original content, such as "video/mpeg" + */ + public String getOriginalMimeType(Uri uri) { + if (null == uri || Uri.EMPTY == uri) { + throw new IllegalArgumentException("Given uri is not valid"); + } + return getOriginalMimeType(convertUriToPath(uri)); + } + + /** * Check whether the given content has valid rights or not * * @param path Path of the protected content @@ -345,6 +620,20 @@ public class DrmManagerClient { } /** + * Check whether the given content has valid rights or not + * + * @param uri The content URI of the data + * @return Status of the rights for the protected content + * @see DrmStore.RightsStatus + */ + public int checkRightsStatus(Uri uri) { + if (null == uri || Uri.EMPTY == uri) { + throw new IllegalArgumentException("Given uri is not valid"); + } + return checkRightsStatus(convertUriToPath(uri)); + } + + /** * Check whether the given content has valid rights or not for specified action. * * @param path Path of the protected content @@ -355,35 +644,77 @@ public class DrmManagerClient { public int checkRightsStatus(String path, int action) { if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) { throw new IllegalArgumentException("Given path or action is not valid"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _checkRightsStatus(mUniqueId, path, action); } /** + * Check whether the given content has valid rights or not for specified action. + * + * @param uri The content URI of the data + * @param action Action to perform + * @return Status of the rights for the protected content + * @see DrmStore.RightsStatus + */ + public int checkRightsStatus(Uri uri, int action) { + if (null == uri || Uri.EMPTY == uri) { + throw new IllegalArgumentException("Given uri is not valid"); + } + return checkRightsStatus(convertUriToPath(uri), action); + } + + /** * Removes the rights associated with the given protected content * * @param path Path of the protected content + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure */ - public void removeRights(String path) { + public int removeRights(String path) { if (null == path || path.equals("")) { throw new IllegalArgumentException("Given path should be non null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } - _removeRights(mUniqueId, path); + return _removeRights(mUniqueId, path); + } + + /** + * Removes the rights associated with the given protected content + * + * @param uri The content URI of the data + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure + */ + public int removeRights(Uri uri) { + if (null == uri || Uri.EMPTY == uri) { + throw new IllegalArgumentException("Given uri is not valid"); + } + return removeRights(convertUriToPath(uri)); } /** * Removes all the rights information of every plug-in associated with * DRM framework. Will be used in master reset + * + * @return + * ERROR_NONE for success + * ERROR_UNKNOWN for failure */ - public void removeAllRights() { - if (getState() == STATE_UNINITIALIZED) { + public int removeAllRights() { + if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } - _removeAllRights(mUniqueId); + int result = ERROR_UNKNOWN; + if (null != mEventHandler) { + Message msg = mEventHandler.obtainMessage(ACTION_REMOVE_ALL_RIGHTS); + result = (mEventHandler.sendMessage(msg)) ? ERROR_NONE : result; + } + return result; } /** @@ -398,7 +729,7 @@ public class DrmManagerClient { public int openConvertSession(String mimeType) { if (null == mimeType || mimeType.equals("")) { throw new IllegalArgumentException("Path or the mimeType should be non null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _openConvertSession(mUniqueId, mimeType); @@ -419,7 +750,7 @@ public class DrmManagerClient { public DrmConvertedStatus convertData(int convertId, byte[] inputData) { if (null == inputData || 0 >= inputData.length) { throw new IllegalArgumentException("Given inputData should be non null"); - } else if (getState() == STATE_UNINITIALIZED) { + } else if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _convertData(mUniqueId, convertId, inputData); @@ -438,7 +769,7 @@ public class DrmManagerClient { * the application on which offset these signature data should be appended. */ public DrmConvertedStatus closeConvertSession(int convertId) { - if (getState() == STATE_UNINITIALIZED) { + if (STATE_UNINITIALIZED == getState()) { throw new IllegalStateException("Not Initialized yet"); } return _closeConvertSession(mUniqueId, convertId); @@ -448,10 +779,68 @@ public class DrmManagerClient { return mCurrentState; } + private int getEventType(int infoType) { + int eventType = -1; + + switch (infoType) { + case DrmInfoRequest.TYPE_REGISTRATION_INFO: + eventType = DrmEvent.TYPE_REGISTERED; + break; + case DrmInfoRequest.TYPE_UNREGISTRATION_INFO: + eventType = DrmEvent.TYPE_UNREGISTERED; + break; + case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO: + eventType = DrmEvent.TYPE_RIGHTS_ACQUIRED; + break; + } + return eventType; + } + + private int getErrorType(int infoType) { + int error = -1; + + switch (infoType) { + case DrmInfoRequest.TYPE_REGISTRATION_INFO: + error = DrmErrorEvent.TYPE_REGISTRATION_FAILED; + break; + case DrmInfoRequest.TYPE_UNREGISTRATION_INFO: + error = DrmErrorEvent.TYPE_UNREGISTRATION_FAILED; + break; + case DrmInfoRequest.TYPE_RIGHTS_ACQUISITION_INFO: + error = DrmErrorEvent.TYPE_RIGHTS_ACQUISITION_FAILED; + break; + } + return error; + } + + /** + * This method expects uri in the following format + * content://media/<table_name>/<row_index> (or) + * file://sdcard/test.mp4 + * + * Here <table_name> shall be "video" or "audio" or "images" + * <row_index> the index of the content in given table + */ + private String convertUriToPath(Uri uri) { + String scheme = uri.getScheme(); + if (null == scheme || scheme.equals("file")) { + return uri.getPath(); + } + String[] projection = new String[] {MediaStore.MediaColumns.DATA}; + Cursor cursor = mContext.getContentResolver().query(uri, projection, null, null, null); + if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) { + throw new IllegalArgumentException("Given Uri could not be found in media store"); + } + int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); + String path = cursor.getString(pathIndex); + cursor.close(); + return path; + } + // private native interfaces - private native void _loadPlugIns(int uniqueId, Object weak_this); + private native int _loadPlugIns(int uniqueId, Object weak_this); - private native void _unloadPlugIns(int uniqueId); + private native int _unloadPlugIns(int uniqueId); private native void _installDrmEngine(int uniqueId, String engineFilepath); @@ -463,7 +852,7 @@ public class DrmManagerClient { private native DrmInfo _acquireDrmInfo(int uniqueId, DrmInfoRequest drmInfoRequest); - private native void _saveRights( + private native int _saveRights( int uniqueId, DrmRights drmRights, String rightsPath, String contentPath); private native int _getDrmObjectType(int uniqueId, String path, String mimeType); @@ -472,13 +861,14 @@ public class DrmManagerClient { private native int _checkRightsStatus(int uniqueId, String path, int action); - private native void _removeRights(int uniqueId, String path); + private native int _removeRights(int uniqueId, String path); - private native void _removeAllRights(int uniqueId); + private native int _removeAllRights(int uniqueId); private native int _openConvertSession(int uniqueId, String mimeType); - private native DrmConvertedStatus _convertData(int uniqueId, int convertId, byte[] inputData); + private native DrmConvertedStatus _convertData( + int uniqueId, int convertId, byte[] inputData); private native DrmConvertedStatus _closeConvertSession(int uniqueId, int convertId); |