Provision the device

Some devices come ready-provisioned, but some do not. Your application must check whether the device has already been provisioned, and if not, to provision it.

Prerequisites

Procedure

The main steps are as follows:

  1. Check if the device has already been provisioned by calling the MediaKeys object's isProvisioned() method.
  2. If the device has not been provisioned:
    1. Initiate a provision request by calling the MediaKeyDeliverySession object's generateProvisionRequest() method.
      The MediaKeyDeliverySession will call onMessage(), passing a MediaKeyMessage.
    2. Get the URL of the provisioning server by using getProvisionServerUrl() to query the MediaKeyMessage object that was returned. 
    3. Contruct an HTTP request using this URL. 
    4. update() the MediaKeyDeliverySession object with the payload that is returned.
    5. Check that the provisioning was successful by calling isProvisioned() again.

Code sample

// Create instance of MediaKeyDeliverySession.MessageEvent
// Note that this listener handles both initialisation requests and licence requests (see Acquire a licence).
private MediaKeyDeliverySession.MessageEvent messageListener = new MediaKeyDeliverySession.MessageEvent() {
  @Override
  public void onMessage(MediaKeyMessage mediaKeyMessage) {
    // This 
    if (mediaKeyMessage.getType().equals("license-request")) {
      // Here, the application constructs an HTML request for the licence server and sends the request.
      // This is not shown here, as it is licence-server-dependent.
      if(REQUEST_OK) {
        // After this call the Widevine encrypted video should be playing.
        mDeliverSession.update(LICENCE_RECEIVED);
      }
    }
    if (mediaKeyMessage.getType().equals("initialisation-request") {
      String serviceUrl = mediaKeyMessage.getProvisionServerUrl() + "&signedRequest=" + new String(mediaKeyMessage.getPayload());
      AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
      // ResponseHandler will pass initialisation/provision request response to the Player
      asyncHttpClient.post(serviceUrl, new ResponseHandler());
    }
  }
}

// Initialise stage, register message listener and check if the device is provisioned, if not, provision it.
public boolean initialize() {
  mDeliverSession = mMediaKeys.createDeliverySession();
  mMessageListener = new MessageListener();
  mDeliverSession.setMessageListener(messageListener);
  if(!mMediaKeys.isProvisioned()) {
    NMPLog.w(TAG, "Device is not provisioned - a provisioning request will now be made");
    mDeliverSession.generateProvisionRequest(); // This will result in an MediaKeyDeliverySession.MessageEvent.onMessage("initialisation-request") event being fired.
  }
  return true;
}

private class ResponseHandler extends AsyncHttpResponseHandler
{
  private static final String TAG = "ResponseHandler";

  public ResponseHandler()
  {
  }

  @Override
  public void onSuccess(int statusCode, Header[] headers, byte[] httpResponse) {
    if (statusCode == 200 && httpResponse.length > 0) {
      // Pass Provisioning response to SDK.
      mDeliverSession.update(httpResponse);
      // Optional, check if device is now provisioned.
      if(mMediaKeys.isProvisioned()) {
        NMPLog.i(TAG, "Device Provisioning OK");
      } else {
        NMPLog.i(TAG, "Device Provisioning FAILED");
      }
    }
  }

  @Override
  public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
    if (errorResponse != null) {
      NMPLog.e(TAG, "AsyncHttpResponseHandler failed: " + new String(errorResponse));
    } else {
      NMPLog.e(TAG, "AsyncHttpResponseHandler failed: " + e.toString());
    }
  }
}

How to test

Test the above code with a device that is known to not yet be provisioned and make sure that the correct message is written to the log.