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