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