1page.title=Licensing Reference 2parent.title=Application Licensing 3parent.link=index.html 4@jd:body 5 6 7 8<div id="qv-wrapper"> 9<div id="qv"> 10 11 <h2>In this document</h2> 12 <ol> 13 <li><a href="#lvl-summary">LVL Classes and Interfaces</a></li> 14 <li><a href="#server-response-codes">Server Response Codes</a></li> 15 <li><a href="#extras">Server Response Extras</a></li> 16 </ol> 17 18</div> 19</div> 20 21 22<h2 id="lvl-summary">LVL Classes and Interfaces</h2> 23 24<p>Table 1 lists all of the source files in the License Verification 25Library (LVL) available through the Android SDK. All of the files are part of 26the <code>com.android.vending.licensing</code> package.</p> 27 28<p class="table-caption"><strong>Table 1.</strong> Summary of LVL library 29classes and interfaces.</p> 30 31<div style="width:99%"> 32<table width="100%"> 33 34<tr> 35<th width="15%">Category</th> 36<th width="20%">Name</th> 37<th width="100%">Description</th> 38</tr> 39 40<tr> 41<td rowspan="2">License check and result</td> 42<td>LicenseChecker</td> 43<td>Class that you instantiate (or subclass) to initiate a license check.</td> 44</tr> 45<tr> 46<td><em>LicenseCheckerCallback</em></td> 47<td>Interface that you implement to handle result of the license check.</td> 48</tr> 49 50<tr> 51<td rowspan="3" width="15%">Policy</td> 52<td width="20%"><em>Policy</em></td> 53<td width="100%">Interface that you implement to determine whether to allow 54access to the application, based on the license response. </td> 55</tr> 56<tr> 57<td>ServerManagedPolicy</td> 58<td width="100%">Default {@code Policy} implementation. Uses settings provided by the 59licensing server to manage local storage of license data, license validity, 60retry.</td> 61</tr> 62<tr> 63<td>StrictPolicy</td> 64<td>Alternative {@code Policy} implementation. Enforces licensing based on a direct 65license response from the server only. No caching or request retry.</td> 66</tr> 67 68<tr> 69<td rowspan="2" width="15%">Data obfuscation <br><em>(optional)</em></td> 70<td width="20%"><em>Obfuscator</em></td> 71<td width="100%">Interface that you implement if you are using a {@code Policy} (such as 72ServerManagedPolicy) that caches license response data in a persistent store. 73Applies an obfuscation algorithm to encode and decode data being written or 74read.</td> 75</tr> 76<tr> 77<td>AESObfuscator</td> 78<td>Default Obfuscator implementation that uses AES encryption/decryption 79algorithm to obfuscate/unobfuscate data.</td> 80</tr> 81 82<tr> 83<td rowspan="2" width="15%">Device limitation<br><em>(optional)</em></td> 84<td width="20%"><em>DeviceLimiter</em></td> 85<td width="100%">Interface that you implement if you want to restrict use of an 86application to a specific device. Called from LicenseValidator. Implementing 87DeviceLimiter is not recommended for most applications because it requires a 88backend server and may cause the user to lose access to licensed applications, 89unless designed with care.</td> 90</tr> 91<tr> 92<td>NullDeviceLimiter</td> 93<td>Default DeviceLimiter implementation that is a no-op (allows access to all 94devices).</td> 95</tr> 96 97<tr> 98<td rowspan="6" width="15%">Library core, no integration needed</td> 99<td width="20%">ResponseData</td> 100<td width="100%">Class that holds the fields of a license response.</td> 101</tr> 102<tr> 103<td>LicenseValidator</td> 104<td>Class that decrypts and verifies a response received from the licensing 105server.</td> 106</tr> 107<tr> 108<td>ValidationException</td> 109<td>Class that indicates errors that occur when validating the integrity of data 110managed by an Obfuscator.</td> 111</tr> 112<tr> 113<td>PreferenceObfuscator</td> 114<td>Utility class that writes/reads obfuscated data to the system's 115{@link android.content.SharedPreferences} store.</td> 116</tr> 117<tr> 118<td><em>ILicensingService</em></td> 119<td>One-way IPC interface over which a license check request is passed to the 120Google Play client.</td> 121</tr> 122<tr> 123<td><em>ILicenseResultListener</em></td> 124<td>One-way IPC callback implementation over which the application receives an 125asynchronous response from the licensing server.</td> 126</tr> 127 128</table> 129</div> 130 131 132<h2 id="server-response-codes">Server Response Codes</h2> 133 134<p>Table 2 lists all of the license response codes supported by the 135licensing server. In general, an application should handle all of these response 136codes. By default, the LicenseValidator class in the LVL provides all of the 137necessary handling of these response codes for you. </p> 138 139<p class="table-caption"><strong>Table 2.</strong> Summary of response codes 140returned by the Google Play server in a license response.</p> 141 142<table> 143 144<tr> 145<th>Response Code</th> 146<th>Description</th> 147<th>Signed?</th> 148<th>Extras</th> 149<th>Comments</th> 150</tr> 151<tr> 152<td>{@code LICENSED}</td> 153<td>The application is licensed to the user. The user has purchased the 154application, or is authorized to download and install the alpha or beta version 155of the application.</td> 156<td>Yes</td> 157<td><code>VT</code>, <code>GT</code>, <code>GR</code></td> 158<td><em>Allow access according to {@code Policy} constraints.</em></td> 159</tr> 160<tr> 161<td>{@code LICENSED_OLD_KEY}</td> 162<td>The application is licensed to the user, but there is an updated application 163version available that is signed with a different key. </td> 164<td>Yes </td> 165<td><code>VT</code>, <code>GT</code>, <code>GR</code>, <code>UT</code></td> 166<td><em>Optionally allow access according to {@code Policy} constraints.</em> 167<p style="margin-top:.5em;">Can indicate that the key pair used by the installed 168application version is invalid or compromised. The application can allow access 169if needed or inform the user that an upgrade is available and limit further use 170until upgrade.</p> 171</td> 172</tr> 173<tr> 174<td>{@code NOT_LICENSED}</td> 175<td>The application is not licensed to the user.</td> 176<td>No</td> 177<td></td> 178<td><em>Do not allow access.</em></td> 179</tr> 180<tr> 181<td>{@code ERROR_CONTACTING_SERVER}</td> 182<td>Local error — the Google Play application was not able to reach the 183licensing server, possibly because of network availability problems. </td> 184<td>No</td> 185<td></td> 186<td><em>Retry the license check according to {@code Policy} retry limits.</em></td> 187</tr> 188<tr> 189<td>{@code ERROR_SERVER_FAILURE}</td> 190<td>Server error — the server could not load the application's key 191pair for licensing.</td> 192<td>No</td> 193<td></td> 194<td><em>Retry the license check according to {@code Policy} retry limits.</em> 195</td> 196</tr> 197<tr> 198<td>{@code ERROR_INVALID_PACKAGE_NAME}</td> 199<td>Local error — the application requested a license check for a package 200that is not installed on the device. </td> 201<td>No </td> 202<td></td> 203<td><em>Do not retry the license check.</em> 204<p style="margin-top:.5em;">Typically caused by a development error.</p> 205</td> 206</tr> 207<tr> 208<td>{@code ERROR_NON_MATCHING_UID}</td> 209<td>Local error — the application requested a license check for a package 210whose UID (package, user ID pair) does not match that of the requesting 211application. </td> 212<td>No </td> 213<td></td> 214<td><em>Do not retry the license check.</em> 215<p style="margin-top:.5em;">Typically caused by a development error.</p> 216</td> 217</tr> 218<tr> 219<td>{@code ERROR_NOT_MARKET_MANAGED}</td> 220<td>Server error — the application (package name) was not recognized by 221Google Play. </td> 222<td>No</td> 223<td></td> 224<td><em>Do not retry the license check.</em> 225<p style="margin-top:.5em;">Can indicate that the application was not published 226through Google Play or that there is an development error in the licensing 227implementation.</p> 228</td> 229</tr> 230 231</table> 232 233<p class="note"><strong>Note:</strong> As documented in <a 234href="{@docRoot}google/play/licensing/setting-up.html#test-env"> 235Setting Up The Testing Environment</a>, the response code can be manually 236overridden for the application developer and any registered test users via the 237Google Play Developer Console.</p> 238 239<p class="note"><strong>Note:</strong> Previously you could test an app by 240uploading an unpublished "draft" version. This functionality is no longer 241supported; instead, you must publish it to the alpha or beta distribution 242channel. For more information, see <a 243href="{@docRoot}google/play/billing/billing_testing.html#draft_apps">Draft Apps 244are No Longer Supported</a>. 245 246 247<h2 id="extras">Server Response Extras</h2> 248 249<p>To assist your application in managing access to the application across the application refund 250period and provide other information, The licensing server includes several pieces of 251information in the license responses. Specifically, the service provides recommended values for the 252application's license validity period, retry grace period, maximum allowable retry count, and other 253settings. If your application uses <a href="{@docRoot}google/play/expansion-files.html">APK 254expansion files</a>, the response also includes the file names, sizes, and URLs. The server appends 255the settings as key-value pairs in the license response "extras" field. </p> 256 257<p>Any {@code Policy} implementation can extract the extras settings from the license 258response and use them as needed. The LVL default {@code Policy} implementation, <a 259href="{@docRoot}google/play/licensing/adding-licensing.html#ServerManagedPolicy">{@code 260ServerManagedPolicy}</a>, serves as a working 261implementation and an illustration of how to obtain, store, and use the 262settings. </p> 263 264<p class="table-caption"><strong>Table 3.</strong> Summary of 265license-management settings supplied by the Google Play server in a license 266response.</p> 267 268<table> 269<tr> 270<th>Extra</th><th>Description</th> 271</tr> 272 273<tr> 274 <td>{@code VT}</td> 275 <td>License validity timestamp. Specifies the date/time at which the current 276(cached) license response expires and must be rechecked on the licensing server. See the section 277below about <a href="#VT">License validity period</a>. 278 </td> 279</tr> 280<tr> 281 <td>{@code GT}</td> 282 <td>Grace period timestamp. Specifies the end of the period during which a 283Policy may allow access to the application, even though the response status is 284{@code RETRY}. <p>The value is managed by the server, however a typical value would be 5 285or more days. See the section 286below about <a href="#GTGR">Retry period and maximum retry count</a>.</p></td> 287</tr> 288<tr> 289 <td>{@code GR}</td> 290 <td>Maximum retries count. Specifies how many consecutive {@code RETRY} license checks 291the {@code Policy} should allow, before denying the user access to the application. 292<p>The value is managed by the server, however a typical value would be "10" or 293higher. See the section 294below about <a href="#GTGR">Retry period and maximum retry count</a>.</p></td> 295</tr> 296<tr> 297 <td>{@code UT}</td> 298 <td>Update timestamp. Specifies the day/time when the most recent update to 299this application was uploaded and published. <p>The server returns this extra 300only for {@code LICENSED_OLD_KEYS} responses, to allow the {@code Policy} to determine how much 301time has elapsed since an update was published with new licensing keys before 302denying the user access to the application. </p></td> 303</tr> 304 305 306<!-- APK EXPANSION FILE RESPONSES --> 307 308<tr> 309 <td>{@code FILE_URL1} or {@code FILE_URL2}</td> 310 <td>The URL for an expansion file (1 is for the main file, 2 is the patch file). Use this to 311download the file over HTTP.</td> 312</tr> 313<tr> 314 <td>{@code FILE_NAME1} or {@code FILE_NAME2}</td> 315 <td>The expansion file's name (1 is for the main file, 2 is the patch file). You must use this 316name when saving the file on the device.</td> 317</tr> 318<tr> 319 <td>{@code FILE_SIZE1} or {@code FILE_SIZE2}</td> 320 <td>The size of the file in bytes (1 is for the main file, 2 is the patch file). Use this to 321assist with downloading and to ensure that enough space is available on the device's shared 322storage location before downloading.</td> 323</tr> 324 325</table> 326 327 328 329<h4 id="VT">License validity period</h4> 330 331<p>The Google Play licensing server sets a license validity period for all 332downloaded applications. The period expresses the interval of time over which an 333application's license status should be considered as unchanging and cacheable by 334a licensing {@code Policy} in the application. The licensing server includes the 335validity period in its response to all license checks, appending an 336end-of-validity timestamp to the response as an extra under the key {@code VT}. A 337{@code Policy} can extract the VT key value and use it to conditionally allow access to 338the application without rechecking the license, until the validity period 339expires. </p> 340 341<p>The license validity signals to a licensing {@code Policy} when it must recheck the 342licensing status with the licensing server. It is <em>not</em> intended to imply 343whether an application is actually licensed for use. That is, when an 344application's license validity period expires, this does not mean that the 345application is no longer licensed for use — rather, it indicates only that 346the {@code Policy} must recheck the licensing status with the server. It follows that, 347as long as the license validity period has not expired, it is acceptable for the 348{@code Policy} to cache the initial license status locally and return the cached license 349status instead of sending a new license check to the server.</p> 350 351<p>The licensing server manages the validity period as a means of helping the 352application properly enforce licensing across the refund period offered by 353Google Play for paid applications. It sets the validity period based on 354whether the application was purchased and, if so, how long ago. Specifically, 355the server sets a validity period as follows:</p> 356 357<ul> 358<li>For a paid application, the server sets the initial license validity period 359so that the license response remains valid for as long as the application is 360refundable. A licensing {@code Policy} in the application may cache the 361result of the initial license check and does not need to recheck the license 362until the validity period has expired.</li> 363<li>When an application is no longer refundable, the server 364sets a longer validity period — typically a number of days. </li> 365 366<!-- TODO: Verify the following behavior is still true w/ OBB: --> 367<li>For a free application, the server sets the validity period to a very high 368value (<code>long.MAX_VALUE</code>). This ensures that, provided the {@code Policy} has 369cached the validity timestamp locally, it will not need to recheck the 370license status of the application in the future.</li> 371</ul> 372 373<p>The {@code ServerManagedPolicy} implementation uses the extracted timestamp 374(<code>mValidityTimestamp</code>) as a primary condition for determining whether 375to recheck the license status with the server before allowing the user access to 376the application. </p> 377 378 379<h4 id="GTGR">Retry period and maximum retry count</h4> 380 381<p>In some cases, system or network conditions can prevent an application's 382license check from reaching the licensing server, or prevent the server's 383response from reaching the Google Play client application. For example, the 384user might launch an application when there is no cell network or data 385connection available—such as when on an airplane—or when the 386network connection is unstable or the cell signal is weak. </p> 387 388<p>When network problems prevent or interrupt a license check, the Google 389Play client notifies the application by returning a {@code RETRY} response code to 390the {@code Policy}'s <code>processServerResponse()</code> method. In the case of system 391problems, such as when the application is unable to bind with Google Play's 392{@code ILicensingService} implementation, the {@code LicenseChecker} library itself calls the 393Policy <code>processServerResonse()</code> method with a {@code RETRY} response code. 394</p> 395 396<p>In general, the {@code RETRY} response code is a signal to the application that an 397error has occurred that has prevented a license check from completing. 398 399<p>The Google Play server helps an application to manage licensing under 400error conditions by setting a retry "grace period" and a recommended maximum 401retries count. The server includes these values in all license check responses, 402appending them as extras under the keys {@code GT} and {@code GR}. </p> 403 404<p>The application {@code Policy} can extract the {@code GT} and {@code GR} extras and use them to 405conditionally allow access to the application, as follows:</p> 406 407<ul> 408<li>For a license check that results in a {@code RETRY} response, the {@code Policy} should 409cache the {@code RETRY} response code and increment a count of {@code RETRY} responses.</li> 410<li>The {@code Policy} should allow the user to access the application, provided that 411either the retry grace period is still active or the maximum retries count has 412not been reached.</li> 413</ul> 414 415<p>The {@code ServerManagedPolicy} uses the server-supplied {@code GT} and {@code GR} values as 416described above. The example below shows the conditional handling of the retry 417responses in the <code>allow()</code> method. The count of {@code RETRY} responses is 418maintained in the <code>processServerResponse()</code> method, not shown. </p> 419 420 421<pre> 422public boolean allowAccess() { 423 long ts = System.currentTimeMillis(); 424 if (mLastResponse == LicenseResponse.LICENSED) { 425 // Check if the LICENSED response occurred within the validity timeout. 426 if (ts <= mValidityTimestamp) { 427 // Cached LICENSED response is still valid. 428 return true; 429 } 430 } else if (mLastResponse == LicenseResponse.RETRY && 431 ts < mLastResponseTime + MILLIS_PER_MINUTE) { 432 // Only allow access if we are within the retry period 433 // or we haven't used up our max retries. 434 return (ts <= mRetryUntil || mRetryCount <= mMaxRetries); 435 } 436 return false; 437}</pre> 438 439