DomainAcquirer Class

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Handles Join Domain requests.

Inheritance Hierarchy

System.Object
  System.Windows.Media.DomainAcquirer

Namespace:  System.Windows.Media
Assembly:  System.Windows (in System.Windows.dll)

Syntax

'Declaration
Public Class DomainAcquirer
public class DomainAcquirer

The DomainAcquirer type exposes the following members.

Constructors

  Name Description
Public methodSupported by Silverlight for Windows Phone DomainAcquirer Initializes a new instance of the DomainAcquirer class.

Top

Properties

  Name Description
Public propertySupported by Silverlight for Windows Phone ChallengeCustomData Gets or sets service specific data that will be sent inside the domain challenge to the PlayReady server.

Top

Methods

  Name Description
Public methodSupported by Silverlight for Windows Phone CancelAsync Called to cancel an ongoing domain operation.
Public methodSupported by Silverlight for Windows Phone Equals(Object) Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected methodSupported by Silverlight for Windows Phone Finalize Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)
Public methodSupported by Silverlight for Windows Phone GetHashCode Serves as a hash function for a particular type. (Inherited from Object.)
Public methodSupported by Silverlight for Windows Phone GetType Gets the Type of the current instance. (Inherited from Object.)
Public methodSupported by Silverlight for Windows Phone JoinDomainAsync Starts an asynchronous join domain operation.
Public methodSupported by Silverlight for Windows Phone LeaveDomainAsync Method used to start an asynchronous leave domain operation.
Protected methodSupported by Silverlight for Windows Phone MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Protected methodSupported by Silverlight for Windows Phone OnCancel Overridden in a derived class to implement cancellation during manual domain operations.
Protected methodSupported by Silverlight for Windows Phone OnJoinDomain Overridden in a derived class to implement manual join domain operations.
Protected methodSupported by Silverlight for Windows Phone OnLeaveDomain Overridden in a derived class to implement manual leave domain operations.
Protected methodSupported by Silverlight for Windows Phone SetJoinDomainResponse Used to set the join domain operation response during a manual join domain operation in a derived DomainAcquirer.
Protected methodSupported by Silverlight for Windows Phone SetLeaveDomainResponse Used to set the Leave domain operation response during a manual leave domain operation in a derived DomainAcquirer.
Public methodSupported by Silverlight for Windows Phone ToString Returns a string that represents the current object. (Inherited from Object.)

Top

Events

  Name Description
Public eventSupported by Silverlight for Windows Phone JoinDomainCompleted Occurs when the join domain operation completes.
Public eventSupported by Silverlight for Windows Phone LeaveDomainCompleted Occurs when the leave domain operation completes.

Top

Remarks

You can derive from this class to implement a manual Join Domain. You might do this to add authentication information to the messages or provide custom error handling (ServiceSpecificError for instance).

Note   If you start multiple asynchronous operations on the same LicenseAcquirer or DomainAcquirer, an InvalidOperationException is thrown.

You can use a DomainAcquirer instance in one of the following two states:

  1. Attached to a LicenseAcquirer.

  2. Through JoinDomainAsync and/or LeaveDomainAsync methods calls.

If you use a DomainAcquirer instance in state 1, then for the rest of its lifetime, you can only use it through that LicenseAcquirer. You cannot reassign the DomainAcquirer instance to another LicenseAcquirer and you cannot use it with the JoinDomainAsync and/or LeaveDomainAsync methods.

If you use a DomainAcquirer instance through JoinDomainAsync and/or LeaveDomainAsync methods calls, then it cannot be assigned to a LicenseAcquirer even after the JoinDomainAsync operation has fully completed.

When you create a DomainAcquirer instance, it is in neither state 1 nor state 2. State 1 is only entered when the DomainAcquirer instance is actually assigned to the LicenseAcquirer. State 2 is entered when JoinDomainAsync is first called (regardless of success or failure of the operation).

Examples

Many media applications that use domain bound licenses will want to join the client to the user’s domain the first time the application is run. This allows the service to control the number of clients per user that have access to media content. You cannot enumerate through domains using the Silverlight API. Because of this, you will want to have the application keep state data itself to know whether the client is joined to a domain.

The following simple example shows how to use the DomainAcquirer class to implement a Join Domain request on first launch of the application.

Guid c_ServiceId = new Guid("{deb47f00-8a3b-416d-9b1e-5d55fd023044}");
Uri c_DomainServerUrl = new Uri("http://domainserver.contoso.com/rmsdk/rightsmanager.asmx");
Uri c_LicenseServerUrl = new Uri("http://licenseserver.contaso.com/rmsdk/rightsmanager.asmx");

public void acquirer_JoinDomainCompleted(object sender, DomainOperationCompletedEventArgs e)
{
    if (e.Error != null)
    {
        // Standard error handling may include logging the error, 
        // retrying, or reporting failure to the user
        // e.CustomData may have additional information depending on 
        // the type of error is reported in e.Message    
    }
    else if (e.Cancelled)
    {
        // Standard cancellation handling
    }
    else
    {
        // Update the ISO store that we are joined to the domain
        // The application may want to store e.AccountId
    }
}

public void JoinDomainOnFirstUse()
{
    if (false == IsJoinedToDomain())
    {
        string friendlyName = PromptUserForClientFriendlyName();
        DomainAcquirer acquirer = new DomainAcquirer();
        acquirer.JoinDomainCompleted +=new 
            EventHandler<JoinDomainCompletedEventArgs>(
            acquirer_JoinDomainCompleted);

        acquirer.JoinDomainAsync(c_ServiceId, 
                                 Guid.Empty, 
                                 c_DomainServerUrl,
                                 friendlyName);
    }
}

You may want to provide functionality to unregister clients by allowing users to go to an account properties page. For example, you can offer an "Unregister this client" button for each device that is currently on the domain and an "Add new client" button to join other devices to the domain. If the user unregisters the current client, a Leave Domain operation is executed to remove the domain keys from the client's persistent license store. In this way, you control the number of clients that can play back controlled content, and the user controls which clients those are.

But what if the user removes a client (client x) from the domain while accessing the online account properties page from another client (client y)? Because client x is disconnected from the Internet at the time of its removal from the domain, the domain license in the persistent license store of client x is not notified of the removal, and the content can still be played on client x.

Many services have strict business rules to regulate such un-registrations. For example, they might limit the number of devices that can be unregistered in this way, require calling customer service to perform a un-registration, or apply fraud detection logic. Therefore, performing a Leave Domain is the preferred way to remove a client from the domain. The logic in the following example shows how the "Unregister this client" button might be implemented.

public void RemoveClientFromAccountButton_OnClick(object sender,
                                                  RoutedEventArgs e)
{
    //
    // The service may want to prompt the user with a "Are you sure?"
    // prompt before removing the client as it will disable media 
    // playback of any domain bound content.
    // 
    // The service will want to look up the currently logged in user’s 
    // account identifier from the ISO store.  The accountId parameter
    // is strictly required, and it is the responsibility of the
    // service to ensure that is is available at this point.
    //
    Guid m_AccountId = accountId;

    DomainAcquirer acquirer = new myDomainAcquirer();

    acquirer.LeaveDomainCompleted += new
        EventHandler<LeaveDomainCompletedEventArgs>(
        acquirer_LeaveDomainCompleted);

    acquirer.LeaveDomainAsync(c_ServiceId,
                              m_AccountId,
                              c_DomainServerUrl);
}

public void acquirer_LeaveDomainCompleted(object sender, DomainOperationCompletedEventArgs e)
{
    if (e.Error != null)
    {
        // Error handling may include logging the error, retrying, or 
        // reporting failure to the user e.CustomData may have 
        // additional information depending on the type of error is 
        // reported in e.Message
    }
    else if (e.Cancelled)
    {
        // Handle cancel
    }
    else
    {
        // Update the ISO store that we left the domain.  Likely means 
        // cleaning up the domain object for the given AccountId.
    }
}

Note   LeaveDomainAsync can fail (perhaps the client is not connected to the internet) but the client will still be removed from the domain. In this case the client thinks that they are not part of a domain yet a service might still think that the client is part of a domain. The service must provide a way to reconcile this mismatch.

The License Acquisition code, whether acquired through the MediaElement or by using the LicenseAcquirer directly, understands the RenewDomainException and DomainRequiredException errors that can be sent back from the license server. If the client receives one of these errors, it tries to use a DomainAcquirer (either a default instance or a user-configured one) to do a Join Domain operation using the parameters supplied in the domain error messages. The logic in the following example shows how little needs to be done at the API level to take advantage of this functionality:

public void RenewDomain()
{

    LicenseAcquirer myLicenseAcquirer = new LicenseAcquirer();
    myLicenseAcquirer.DomainAcquirer = new myDomainAcquirer();

    mediaElement.LicenseAcquirer = myLicenseAcquirer;
    mediaElement.LicenseAcquirer.LicenseServerUriOverride =
        c_LicenseServerUrl;
    mediaElement.Source = new
        Uri("https://contoso.com/content.wmv");


    //
    //  If the license server decides that the client does not have a 
    //  domain membership, the domain membership is out of date, 
    //  then a DomainRequiredException or RenewDomainException respectively 
    //  will be thrown and the client will send back a response containing
    //  the necessary information (url, serviceid, accountid, etc) to 
    //  send to the domain server.  The license acquisition pipeline 
    //  would treat this somewhat like an Indiv message in that
    //  it would do the join domain and then restart the license 
    //  acquisition.
    //
    //  Note that a customized DomainAcquirer was provided so the 
    //  OnJoinDomain method will be called to allow 
    //  authentication information to be provided with the Join Domain 
    //  request.
    //
    mediaElement.Play();
}

Version Information

Silverlight

Supported in: 5, 4

Silverlight for Windows Phone

Supported in: Windows Phone OS 7.1

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.