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