page.title=Licensing Reference parent.title=Application Licensing parent.link=index.html @jd:body

In this document

  1. LVL Classes and Interfaces
  2. Server Response Codes
  3. Server Response Extras

LVL Classes and Interfaces

Table 1 lists all of the source files in the License Verification Library (LVL) available through the Android SDK. All of the files are part of the com.android.vending.licensing package.

Table 1. Summary of LVL library classes and interfaces.

Category Name Description
License check and result LicenseChecker Class that you instantiate (or subclass) to initiate a license check.
LicenseCheckerCallback Interface that you implement to handle result of the license check.
Policy Policy Interface that you implement to determine whether to allow access to the application, based on the license response.
ServerManagedPolicy Default {@code Policy} implementation. Uses settings provided by the licensing server to manage local storage of license data, license validity, retry.
StrictPolicy Alternative {@code Policy} implementation. Enforces licensing based on a direct license response from the server only. No caching or request retry.
Data obfuscation
(optional)
Obfuscator Interface that you implement if you are using a {@code Policy} (such as ServerManagedPolicy) that caches license response data in a persistent store. Applies an obfuscation algorithm to encode and decode data being written or read.
AESObfuscator Default Obfuscator implementation that uses AES encryption/decryption algorithm to obfuscate/unobfuscate data.
Device limitation
(optional)
DeviceLimiter Interface that you implement if you want to restrict use of an application to a specific device. Called from LicenseValidator. Implementing DeviceLimiter is not recommended for most applications because it requires a backend server and may cause the user to lose access to licensed applications, unless designed with care.
NullDeviceLimiter Default DeviceLimiter implementation that is a no-op (allows access to all devices).
Library core, no integration needed ResponseData Class that holds the fields of a license response.
LicenseValidator Class that decrypts and verifies a response received from the licensing server.
ValidationException Class that indicates errors that occur when validating the integrity of data managed by an Obfuscator.
PreferenceObfuscator Utility class that writes/reads obfuscated data to the system's {@link android.content.SharedPreferences} store.
ILicensingService One-way IPC interface over which a license check request is passed to the Google Play client.
ILicenseResultListener One-way IPC callback implementation over which the application receives an asynchronous response from the licensing server.

Server Response Codes

Table 2 lists all of the license response codes supported by the licensing server. In general, an application should handle all of these response codes. By default, the LicenseValidator class in the LVL provides all of the necessary handling of these response codes for you.

Table 2. Summary of response codes returned by the Google Play server in a license response.

Response Code Description Signed? Extras Comments
{@code LICENSED} The application is licensed to the user. The user has purchased the application or the application only exists as a draft. Yes VTGT, GR Allow access according to {@code Policy} constraints.
{@code LICENSED_OLD_KEY} The application is licensed to the user, but there is an updated application version available that is signed with a different key. Yes VT, GT, GR, UT Optionally allow access according to {@code Policy} constraints.

Can indicate that the key pair used by the installed application version is invalid or compromised. The application can allow access if needed or inform the user that an upgrade is available and limit further use until upgrade.

{@code NOT_LICENSED} The application is not licensed to the user. No Do not allow access.
{@code ERROR_CONTACTING_SERVER} Local error — the Google Play application was not able to reach the licensing server, possibly because of network availability problems. No Retry the license check according to {@code Policy} retry limits.
{@code ERROR_SERVER_FAILURE} Server error — the server could not load the application's key pair for licensing. No Retry the license check according to {@code Policy} retry limits.
{@code ERROR_INVALID_PACKAGE_NAME} Local error — the application requested a license check for a package that is not installed on the device. No Do not retry the license check.

Typically caused by a development error.

{@code ERROR_NON_MATCHING_UID} Local error — the application requested a license check for a package whose UID (package, user ID pair) does not match that of the requesting application. No Do not retry the license check.

Typically caused by a development error.

{@code ERROR_NOT_MARKET_MANAGED} Server error — the application (package name) was not recognized by Google Play. No Do not retry the license check.

Can indicate that the application was not published through Google Play or that there is an development error in the licensing implementation.

Note: As documented in Setting Up The Testing Environment, the response code can be manually overridden for the application developer and any registered test users via the Google Play Developer Console.

Additionally, as noted above, applications that are in draft mode (in other words, applications that have been uploaded but have never been published) will return {@code LICENSED} for all users, even if not listed as a test user. Since the application has never been offered for download, it is assumed that any users running it must have obtained it from an authorized channel for testing purposes.

Server Response Extras

To assist your application in managing access to the application across the application refund period and provide other information, The licensing server includes several pieces of information in the license responses. Specifically, the service provides recommended values for the application's license validity period, retry grace period, maximum allowable retry count, and other settings. If your application uses APK expansion files, the response also includes the file names, sizes, and URLs. The server appends the settings as key-value pairs in the license response "extras" field.

Any {@code Policy} implementation can extract the extras settings from the license response and use them as needed. The LVL default {@code Policy} implementation, {@code ServerManagedPolicy}, serves as a working implementation and an illustration of how to obtain, store, and use the settings.

Table 3. Summary of license-management settings supplied by the Google Play server in a license response.

ExtraDescription
{@code VT} License validity timestamp. Specifies the date/time at which the current (cached) license response expires and must be rechecked on the licensing server. See the section below about License validity period.
{@code GT} Grace period timestamp. Specifies the end of the period during which a Policy may allow access to the application, even though the response status is {@code RETRY}.

The value is managed by the server, however a typical value would be 5 or more days. See the section below about Retry period and maximum retry count.

{@code GR} Maximum retries count. Specifies how many consecutive {@code RETRY} license checks the {@code Policy} should allow, before denying the user access to the application.

The value is managed by the server, however a typical value would be "10" or higher. See the section below about Retry period and maximum retry count.

{@code UT} Update timestamp. Specifies the day/time when the most recent update to this application was uploaded and published.

The server returns this extra only for {@code LICENSED_OLD_KEYS} responses, to allow the {@code Policy} to determine how much time has elapsed since an update was published with new licensing keys before denying the user access to the application.

{@code FILE_URL1} or {@code FILE_URL2} The URL for an expansion file (1 is for the main file, 2 is the patch file). Use this to download the file over HTTP.
{@code FILE_NAME1} or {@code FILE_NAME2} The expansion file's name (1 is for the main file, 2 is the patch file). You must use this name when saving the file on the device.
{@code FILE_SIZE1} or {@code FILE_SIZE2} The size of the file in bytes (1 is for the main file, 2 is the patch file). Use this to assist with downloading and to ensure that enough space is available on the device's shared storage location before downloading.

License validity period

The Google Play licensing server sets a license validity period for all downloaded applications. The period expresses the interval of time over which an application's license status should be considered as unchanging and cacheable by a licensing {@code Policy} in the application. The licensing server includes the validity period in its response to all license checks, appending an end-of-validity timestamp to the response as an extra under the key {@code VT}. A {@code Policy} can extract the VT key value and use it to conditionally allow access to the application without rechecking the license, until the validity period expires.

The license validity signals to a licensing {@code Policy} when it must recheck the licensing status with the licensing server. It is not intended to imply whether an application is actually licensed for use. That is, when an application's license validity period expires, this does not mean that the application is no longer licensed for use — rather, it indicates only that the {@code Policy} must recheck the licensing status with the server. It follows that, as long as the license validity period has not expired, it is acceptable for the {@code Policy} to cache the initial license status locally and return the cached license status instead of sending a new license check to the server.

The licensing server manages the validity period as a means of helping the application properly enforce licensing across the refund period offered by Google Play for paid applications. It sets the validity period based on whether the application was purchased and, if so, how long ago. Specifically, the server sets a validity period as follows:

The {@code ServerManagedPolicy} implementation uses the extracted timestamp (mValidityTimestamp) as a primary condition for determining whether to recheck the license status with the server before allowing the user access to the application.

Retry period and maximum retry count

In some cases, system or network conditions can prevent an application's license check from reaching the licensing server, or prevent the server's response from reaching the Google Play client application. For example, the user might launch an application when there is no cell network or data connection available—such as when on an airplane—or when the network connection is unstable or the cell signal is weak.

When network problems prevent or interrupt a license check, the Google Play client notifies the application by returning a {@code RETRY} response code to the {@code Policy}'s processServerResponse() method. In the case of system problems, such as when the application is unable to bind with Google Play's {@code ILicensingService} implementation, the {@code LicenseChecker} library itself calls the Policy processServerResonse() method with a {@code RETRY} response code.

In general, the {@code RETRY} response code is a signal to the application that an error has occurred that has prevented a license check from completing.

The Google Play server helps an application to manage licensing under error conditions by setting a retry "grace period" and a recommended maximum retries count. The server includes these values in all license check responses, appending them as extras under the keys {@code GT} and {@code GR}.

The application {@code Policy} can extract the {@code GT} and {@code GR} extras and use them to conditionally allow access to the application, as follows:

The {@code ServerManagedPolicy} uses the server-supplied {@code GT} and {@code GR} values as described above. The example below shows the conditional handling of the retry responses in the allow() method. The count of {@code RETRY} responses is maintained in the processServerResponse() method, not shown.

    
public boolean allowAccess() {
    long ts = System.currentTimeMillis();
    if (mLastResponse == LicenseResponse.LICENSED) {
        // Check if the LICENSED response occurred within the validity timeout.
        if (ts <= mValidityTimestamp) {
            // Cached LICENSED response is still valid.
            return true;
        }
    } else if (mLastResponse == LicenseResponse.RETRY &&
                ts < mLastResponseTime + MILLIS_PER_MINUTE) {
        // Only allow access if we are within the retry period or we haven't used up our
        // max retries.
        return (ts <= mRetryUntil || mRetryCount <= mMaxRetries);
    }
    return false;
}