| Scott Main | 92c8724 | 2011-02-15 17:59:36 -0800 | [diff] [blame] | 1 | page.title=Application Licensing |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 2 | @jd:body |
| 3 | |
| 4 | <div id="qv-wrapper"> |
| 5 | <div id="qv"> |
| 6 | |
| Scott Main | ec80d7f | 2010-09-24 16:17:27 -0700 | [diff] [blame] | 7 | <h2>Quickview</h2> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 8 | <ul> |
| 9 | <li>Licensing lets you protect your application on any device that includes Android Market.</li> |
| 10 | <li>Your app maintains control of how it enforces its licensing status. </li> |
| 11 | <li>Adding licensing to an app is straightforward, using the library available through the SDK.</li> |
| 12 | <li>The service is free and is available to all developers who publish on Android Market. </li> |
| 13 | </ul> |
| 14 | |
| 15 | <h2>In this document</h2> |
| 16 | <ol> |
| 17 | <li><a href="#account">Setting Up A Publisher Account</a></li> |
| 18 | <li><a href="#dev-setup">Setting Up the Development Environment</a></li> |
| 19 | <li><a href="#app-integration">Integrating the LVL with Your Application</a> |
| 20 | <ol> |
| 21 | <li><a href="#add-library">Including the LVL</a></li> |
| 22 | <li><a href="#manifest-permission">Adding the licensing permission</a></li> |
| 23 | <li><a href="#impl-Policy">Implementing a Policy</a></li> |
| 24 | <li><a href="#impl-Obfuscator">Implementing an Obfuscator</a></li> |
| 25 | <li><a href="#impl-lc">Checking the license</a></li> |
| 26 | <li><a href="#impl-DeviceLimiter">Implementing a DeviceLimiter</a></li> |
| 27 | </ol></li> |
| 28 | <li><a href="#test-env">Setting Up the Test Environment</a> |
| 29 | <ol> |
| 30 | <li><a href="#test-response">Test responses</a></li> |
| 31 | <li><a href="#test-acct-setup">Test accounts</a></li> |
| 32 | <li><a href="#acct-signin">Signing in on a device or emulator</a></li> |
| 33 | </ol></li> |
| 34 | <li><a href="#app-obfuscation">Obfuscating Your Application</a></li> |
| 35 | <li><a href="#app-publishing">Publishing a Licensed Application</a></li> |
| 36 | <li><a href="#support">Where to Get Support</a></li> |
| 37 | </ol> |
| 38 | |
| 39 | <h2>Appendix</h2> |
| 40 | <ol> |
| 41 | <li><a href="#lvl-summary">Summary of LVL Classes and Interfaces</a></li> |
| 42 | <li><a href="#server-response-codes">Server Response Codes</a></li> |
| 43 | <li><a href="#extras">Server Response Extras</a></li> |
| 44 | </ol> |
| 45 | |
| 46 | </div> |
| 47 | </div> |
| 48 | |
| 49 | <p>Android Market offers a licensing service that lets you enforce licensing |
| 50 | policies for paid applications that you publish through Android Market. With |
| 51 | Android Market Licensing, your applications can query Android Market at run time to |
| 52 | obtain their licensing status for the current user, then allow or disallow |
| 53 | further use as appropriate. </p> |
| 54 | |
| 55 | <p>Using the service, you can apply a flexible licensing policy on an |
| 56 | application-by-application basis — each application can enforce licensing |
| 57 | in the way most appropriate for it. If necessary, an application can apply custom |
| 58 | constraints based on the licensing status obtained from Android Market. |
| 59 | For example, an application can check the licensing status and then apply custom |
| 60 | constraints that allow the user to run it unlicensed for a specific number |
| 61 | of times, or for a specific validity period. An application can also restrict use of the |
| 62 | application to a specific device, in addition to any other constraints. </p> |
| 63 | |
| 64 | <p>The licensing service is a secure means of controlling access to your |
| 65 | applications. When an application checks the licensing status, the Market server |
| 66 | signs the licensing status response using a key pair that is uniquely associated |
| 67 | with the publisher account. Your application stores the public key in its |
| 68 | compiled <code>.apk</code> file and uses it to verify the licensing status |
| 69 | response.</p> |
| 70 | |
| 71 | <p>Any application that you publish through Android Market can use the Android |
| 72 | Market Licensing service. No special account or registration is needed. |
| 73 | Additionally, because the service uses no dedicated framework APIs, you can add |
| 74 | licensing to any legacy application that uses a minimum API level of 3 or |
| 75 | higher.</p> |
| 76 | |
| 77 | <p>To help you add licensing to your application, the Android SDK provides |
| 78 | library sources that you can include in your application project. The |
| 79 | License Verification Library (LVL) handles all of |
| 80 | the licensing-related communication with the Android Market client and the |
| 81 | licensing service. With the LVL integrated, your application can determine its |
| 82 | licensing status for the current user by simply calling a library checker method |
| 83 | and implementing a callback that receives the status.</p> |
| 84 | |
| 85 | <p>This document explains how the licensing service works and how to add it to |
| 86 | your application. </p> |
| 87 | |
| 88 | |
| 89 | <h2 id="overview">Overview</h2> |
| 90 | |
| 91 | <p>Android Market Licensing is a network-based service that lets an application |
| 92 | on an Android-powered device query a trusted licensing server, to determine |
| 93 | whether the application is licensed to the current device user. After receiving |
| 94 | the server response, the application can then allow or disallow further use of |
| 95 | the application as needed. In the service, the role of the licensing server is |
| 96 | to provide the license status for the current user; the application itself is |
| 97 | responsible for querying the server and conditionally granting access to the |
| 98 | application. </p> |
| 99 | |
| 100 | <h4>Application, Android Market client, and server</h4> |
| 101 | |
| 102 | <p>The licensing service is based on the capability of the Android Market server |
| 103 | to determine whether a given user is licensed to use a given application. The |
| 104 | server considers a user licensed if the user is recorded to have purchased the |
| 105 | application, or if the application is available for free. To properly identify |
| 106 | the user and determine the license status, the server requires information about |
| 107 | the application and user — the application and the Android Market client |
| 108 | work together to assemble the information and pass it to the server. </p> |
| 109 | |
| 110 | <p>In the licensing service, an application does not query the licensing server |
| 111 | directly, but instead calls the Android Market client over remote IPC to |
| 112 | initiate a license request. In the license request:</p> |
| 113 | |
| 114 | <ul> |
| 115 | <li>The application provides its package name and a nonce that is later used to |
| 116 | validate any response from the server, as well as a callback over which the |
| 117 | response can be returned asynchronously.</li> |
| 118 | <li>The Android Market client, which has greater permissions than the |
| 119 | application, collects the necessary information about the user and the device, |
| 120 | such as the device's primary Google account username, IMSI, and other |
| 121 | information. It then sends the license check request to the server on behalf of |
| 122 | the application.</li> |
| 123 | <li>The server evaluates the request using all available information, attempting |
| 124 | to establish the user's identity to a sufficient level of confidence. The server |
| 125 | then checks the user identity against purchase records for the application and |
| 126 | returns a license response, which the Android Market client returns to the |
| 127 | application over the IPC callback.</li> |
| 128 | </ul> |
| 129 | |
| 130 | <p>Notice that during a license check, the application does not manage any |
| 131 | network connections or use any licensing related APIs in the Android platform. |
| 132 | </p> |
| 133 | |
| 134 | <div class="figure" style="width:469px"> |
| 135 | <img src="{@docRoot}images/licensing_arch.png" alt=""/> |
| 136 | <p class="img-caption"><strong>Figure 1.</strong> Your application initiates a |
| 137 | license check through the LVL and the Android Market |
| 138 | client, which handles communication with the Market server.</p> |
| 139 | </div> |
| 140 | |
| 141 | <h4>License responses secured through public key cryptography</h4> |
| 142 | |
| 143 | <p>To ensure the integrity of each license query, the server signs the license |
| 144 | response data using an RSA key pair that is shared exclusively between the |
| 145 | server and the application publisher.</p> |
| 146 | |
| 147 | <p>The licensing service generates a single licensing key pair for each |
| 148 | publisher account and exposes the public key in the account's profile page. The |
| 149 | publisher copies the public key and embeds it in the application source code, |
| 150 | then compiles and publishes the <code>.apk.</code> The server retains the |
| 151 | private key internally and uses it to sign license responses for applications |
| 152 | published on that account. </p> |
| 153 | |
| 154 | <p>When the application receives a signed response, it uses the embedded public |
| 155 | key to verify the data. The use of public key cryptography in the licensing |
| 156 | service makes it possible for the application to detect responses that have been |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 157 | tampered with or that are spoofed.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 158 | |
| 159 | <h4>Use of licensing in your application</h4> |
| 160 | |
| 161 | <p>To use licensing in your application, add code to the application to |
| 162 | initiate a license check request and handle the response when it is received. |
| 163 | You can choose when, and how often, you want your application to check its |
| 164 | license and you have full control over how it handles the response, verifies the |
| 165 | signed response data, and enforces access controls. </p> |
| 166 | |
| 167 | <p>To simplify the process of adding support for licensing, download and |
| 168 | integrate the Licensing Verification Library, described below. Integration is |
| 169 | straightforward.</p> |
| 170 | |
| 171 | <p>When you are finished integrating the LVL, use a test environment |
| 172 | provided by the publisher site to test your application's handling of server |
| 173 | responses. </p> |
| 174 | |
| 175 | <p>Finally, publish the application <code>.apk</code> on Market using the |
| 176 | normal process. If you previously used the copy-protection provided by Android |
| 177 | Market, you can remove it from applications that use licensing. </p> |
| 178 | |
| 179 | <h4>Licensing Verification Library simplifies implementation</h4> |
| 180 | |
| 181 | <p>The Android SDK includes a License Verification Library (LVL) that you can |
| 182 | download and use as the basis for your application's licensing implementation. |
| 183 | The LVL greatly simplifies the process of adding licensing to your application |
| 184 | and helps ensure a more secure, robust implementation for your application. The |
| 185 | LVL provides internal classes that handle most of the standard operations of a |
| 186 | license query, such as contacting Android Market to initiate a license request |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 187 | and verifying and validating the responses. It also exposes key interfaces that |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 188 | let you easily plug in your custom code for defining licensing policy and |
| 189 | managing access as needed by your application. The key LVL interfaces are: </p> |
| 190 | |
| 191 | <ul> |
| 192 | <li>Policy — your implementation determines whether to allow access to the |
| 193 | application, based on the license response received from the server and any |
| 194 | other data available (such as from a backend server associated with your |
| 195 | application). The implementation can evaluate the various fields of the license |
| 196 | response and apply other constraints, if needed. The implementation also lets |
| 197 | you manage the handling of license checks that result in errors, such as network |
| 198 | errors.</li> |
| 199 | <li>LicenseCheckerCallback — your implementation manages access to the |
| 200 | application, based on the result of the Policy's handling of the license |
| 201 | response. Your implementation can manage access in any way needed, including |
| 202 | displaying the license result in the UI or directing the user to purchase the |
| 203 | application (if not currently licensed). </li> |
| 204 | </ul> |
| 205 | |
| 206 | <p>To help you get started with a Policy, the LVL provides two fully complete |
| 207 | Policy implementations that you can use without modification or adapt to your |
| 208 | needs:</p> |
| 209 | |
| 210 | <ul> |
| 211 | <li><a href="#ServerManagedPolicy">ServerManagedPolicy</a> is a flexible Policy |
| 212 | that uses settings provided by the licensing server to manage response caching |
| 213 | and access to the application while the device is offline (such as when the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 214 | user is on an airplane). For most applications, the use of |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 215 | ServerManagedPolicy is highly recommended. </li> |
| 216 | <li><a href="#StrictPolicy">StrictPolicy</a> is a restrictive Policy that |
| 217 | does not cache any response data and allows the application access <em>only</em> |
| 218 | when the server returns a licensed response.</li> |
| 219 | </ul> |
| 220 | |
| 221 | <p>The LVL is available as a downloadable component of the Android SDK. The |
| 222 | component includes both the LVL itself and an example application that shows how |
| 223 | the library should be integrated with your application and how your application |
| 224 | should manage response data, UI interaction, and error conditions. </p> |
| 225 | |
| 226 | <p>The LVL sources are provided as an Android <em>library project</em>, which |
| 227 | means that you can maintain a single set of library sources and share them |
| 228 | across multiple applications. A full test environment is also available through |
| 229 | the SDK, so you can develop and test the licensing implementation in your |
| 230 | applications before publishing them, even if you don't have access to a |
| 231 | physical device.</p> |
| 232 | |
| 233 | <h4>Requirements and limitations</h4> |
| 234 | |
| 235 | <p>Android Market Licensing is designed to let you apply license controls to |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 236 | applications that you publish through Android Market. The service is not |
| 237 | designed to let you control access to applications that are not published |
| 238 | through Android Market or that are run on devices that do not offer the Android |
| 239 | Market client. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 240 | |
| 241 | <p>Here are some points to keep in mind as you implement licensing in your |
| 242 | application: </p> |
| 243 | |
| 244 | <ul> |
| 245 | <li>Only paid applications published through Market can use the |
| 246 | service. </li> |
| 247 | <li>An application can use the service only if the Android Market client is |
| 248 | installed on its host device and the device is running Android 1.5 (API level 3) |
| 249 | or higher.</li> |
| 250 | <li>To complete a license check, the licensing server must be accessible over |
| 251 | the network. You can implement license caching behaviors to manage access when |
| 252 | there is no network connectivity. </li> |
| 253 | <li>The security of your application's licensing controls ultimately relies on |
| 254 | the design of your implementation itself. The service provides the building |
| 255 | blocks that let you securely check licensing, but the actual enforcement and |
| 256 | handling of the license are factors in your control. By following the best |
| 257 | practices in this document, you can help ensure that your implementation will be |
| 258 | secure.</li> |
| 259 | <li>Adding licensing to an application does not affect the way the application |
| 260 | functions when run on a device that does not offer Android Market.</li> |
| 261 | <li>Licensing is currently for paid apps only, since free apps are considered |
| 262 | licensed for all users. If your application is already published as free, |
| 263 | you won't be able to upload a new version that uses licensing.</li> |
| 264 | </ul> |
| 265 | |
| 266 | <h4>Replacement for copy protection</h4> |
| 267 | |
| 268 | <p>Android Market Licensing is a flexible, secure mechanism for controlling |
| 269 | access to your applications. It effectively replaces the copy-protection |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 270 | mechanism offered on Android Market and gives you wider distribution |
| 271 | potential for your applications. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 272 | |
| 273 | <ul> |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 274 | <li>A limitation of the legacy copy-protection mechanism on Android Market is |
| 275 | that applications using it can be installed only on compatible devices that |
| 276 | provide a secure internal storage environment. For example, a copy-protected |
| 277 | application cannot be downloaded from Market to a device that provides root |
| 278 | access, and the application cannot be installed to a device's SD card. </li> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 279 | <li>With Android Market licensing, you can move to a license-based model in |
| 280 | which access is not bound to the characteristics of the host device, but to your |
| 281 | publisher account on Android Market and the licensing policy that you define. |
| 282 | Your application can be installed and controlled on any compatible device on |
| 283 | any storage, including SD card.</li> |
| 284 | </ul> |
| 285 | |
| 286 | <p>Although no license mechanism can completely prevent all unauthorized use, |
| 287 | the licensing service lets you control access for most types of normal usage, |
| 288 | across all compatible devices, locked or unlocked, that run Android 1.5 or |
| 289 | higher version of the platform.</p> |
| 290 | |
| 291 | <p>The sections below describe how to add Android Market licensing to your |
| 292 | applications. </p> |
| 293 | |
| 294 | <h2 id="account">Setting Up a Publisher Account</h2> |
| 295 | |
| 296 | <p>Android Market licensing lets you manage access to applications that |
| 297 | users have downloaded from Android Market. To use licensing in an application, |
| 298 | you need to have a publisher account on Android Market so that you can |
| 299 | publish the application to users. </p> |
| 300 | |
| 301 | <p>If you don't already have a publisher account, you need to register for one |
| 302 | using your Google account and agree to the terms of service. Once you are |
| 303 | registered, you can upload applications at your convenience and begin debugging |
| 304 | and testing your licensing implementation. For more information about publishing |
| 305 | on Android Market, see <a |
| 306 | href="{@docRoot}guide/publishing/publishing.html">Publishing Your |
| 307 | Applications</a></p> |
| 308 | |
| 309 | <p>To register as an Android Market developer and set up your publisher account, |
| 310 | visit the Android Market publisher site:</p> |
| 311 | |
| 312 | <p style="margin-left:2em;"><a |
| 313 | href="http://market.android.com/publish">http://market.android.com/publish</a> |
| 314 | </p> |
| 315 | |
| 316 | <p>If you already have a publisher account on Android Market, use your existing |
| 317 | account to set up licensing. You <em>do not</em> need to register for a new |
| 318 | account to support licensing (and doing so is not recommended, especially if you |
| 319 | are adding licensing support to applications that you have already published). |
| 320 | In all cases, if you have published applications, you manage licensing for those |
| 321 | applications through the account on which the applications are published. </p> |
| 322 | |
| 323 | <p>Once your publisher account is set up, use the account to:</p> |
| 324 | |
| 325 | <ul> |
| 326 | <li>Obtain a public key for licensing</li> |
| 327 | <li>Debug and test an application's licensing implementation, prior to |
| 328 | publishing the application</li> |
| 329 | <li>Publish the applications to which you have added licensing support</li> |
| 330 | </ul> |
| 331 | |
| 332 | <h4>Administrative settings for licensing</h4> |
| 333 | |
| 334 | <p>Once you are signed into your publisher account, you can manage several |
| 335 | administrative controls for Android Market licensing. The controls are available |
| 336 | in the Edit Profile page, in the "Licensing" panel, shown below. The controls |
| 337 | let you: </p> |
| 338 | |
| 339 | <ul> |
| 340 | <li>Set up multiple "test accounts", identified by email address. The licensing |
| 341 | server allows users signed into test accounts on a device or emulator to send |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 342 | license checks and receive static test responses.</li> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 343 | <li>Obtain the account's public key for licensing. When you are implementing |
| 344 | licensing in an application, you must copy the public key string into the |
| 345 | application.</li> |
| 346 | <li>Configure static test responses that the server sends, when it receives a |
| 347 | license check for an application uploaded to the publisher account, from a user |
| 348 | signed in to the publisher account or a test account.</li> |
| 349 | </ul> |
| 350 | |
| 351 | <div style="margin-bottom:2em;"> |
| 352 | |
| 353 | <img src="{@docRoot}images/licensing_public_key.png" style="text-align:left;margin-bottom:0;" /> |
| 354 | <div style="margin:0 2em;padding:0"><strong>Figure 2.</strong> The Licensing |
| 355 | panel of your account's Edit Profile page lets you manage administrative |
| 356 | settings for licensing.</div> |
| 357 | </div> |
| 358 | |
| 359 | <p>For more information about how to work with test accounts and static test |
| 360 | responses, see <a href="#test-env">Setting Up a Testing Environment</a>, below. |
| 361 | |
| 362 | <h2 id="dev-setup">Setting Up the Development Environment</h2> |
| 363 | |
| 364 | <p>Once you've set up your publisher account on Android Market, the next step is |
| 365 | to set up your development environment for licensing. </p> |
| 366 | |
| 367 | <p>Setting up your environment for licensing involves these tasks:</p> |
| 368 | |
| 369 | <ol> |
| 370 | <li><a href="#download-sdk">Downloading the latest SDK</a>, if you haven't already done so </li> |
| Bill Gruber | 9a693ed | 2011-04-08 17:55:17 -0700 | [diff] [blame] | 371 | <li><a href="#runtime-setup">Setting up the runtime environment</a> for development</li> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 372 | <li><a href="#download-lvl">Downloading the Market Licensing component</a> into your SDK </li> |
| 373 | <li><a href="#lvl-setup">Setting up the Licensing Verification Library</a></li> |
| 374 | <li><a href="#add-library">Including the LVL library project in your application</a></li> |
| 375 | </ol> |
| 376 | |
| 377 | <p>The sections below describe these tasks. When you are done with setup, |
| 378 | you can begin <a href="#app-integration">integrating the LVL into your applications</a>.</p> |
| 379 | |
| 380 | <p>To get started, you need to set up a proper runtime environment on which |
| 381 | you can run, debug and test your application's implementation of license |
| 382 | checking and enforcement. </p> |
| 383 | |
| 384 | |
| 385 | <h3 id="download-sdk">Downloading the latest SDK</h3> |
| 386 | |
| 387 | <div class="sidebox-wrapper"> |
| 388 | <div class="sidebox"> |
| 389 | <h2>Licensing sample application</h2> |
| 390 | |
| 391 | <p>To work with Android Market licensing, you need a functioning Android |
| 392 | application to which you can add licensing support. </p> |
| 393 | |
| 394 | <p style="margin-top:.5em;">If you are new to Android |
| 395 | and don't yet have a functioning application, the LVL component includes a sample |
| 396 | application that you can set up as a new application project. The sample provides |
| 397 | a complete, working example of how licensing works. For more information, see <a |
| 398 | href="#download-lvl">Downloading the LVL</a>.</p> |
| 399 | |
| 400 | </div> |
| 401 | </div> |
| 402 | |
| 403 | <p>If you haven't done so, you need to download the Android SDK before you can |
| 404 | develop Android applications. The SDK provides the tools that you need to build |
| 405 | and debug Android applications, including applications that use Android Market |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 406 | licensing. For complete information, including installation instructions, see |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 407 | the <a href="{@docRoot}sdk/index.html">Android SDK</a>. </p> |
| 408 | |
| 409 | <p>If you have already installed the SDK, make sure to update the |
| 410 | SDK tools and ADT Plugin to the latest versions. You can update the SDK tools |
| 411 | using the Android SDK and AVD Manager and ADT through <strong>Help</strong> > |
| 412 | <strong>Software Updates...</strong> in Eclipse. </p> |
| 413 | |
| 414 | <p>After you've installed the latest SDK and tools, set up your development |
| 415 | environment as described below. </p> |
| 416 | |
| 417 | |
| 418 | <h3 id="runtime-setup">Setting up the runtime environment</h3> |
| 419 | |
| 420 | <p>As described earlier, applications check licensing status not by contacting |
| 421 | the licensing server directly, but by binding to a service provided by the |
| 422 | Android Market application and initiating a license check request. The Android |
| 423 | Market service then handles the direct communication with the licensing server |
| 424 | and finally routes the response back to your application. To debug and test |
| 425 | licensing in your application, you need to set up a runtime environment that |
| 426 | includes the necessary Android Market service, so that your application is able |
| 427 | to send license check requests to the licensing server. </p> |
| 428 | |
| 429 | <p>There are two types of runtime environment that you can use: </p> |
| 430 | |
| 431 | <ul> |
| 432 | <li>An Android-powered device that includes the Android Market application, or</li> |
| 433 | <li>An Android emulator running the Google APIs Add-on, API level 8 (release 2) |
| 434 | or higher</li> |
| 435 | </ul> |
| 436 | |
| 437 | <p>The sections below provide more information. </p> |
| 438 | |
| 439 | <h4 id="runtime-device">Running on a device</h4> |
| 440 | |
| 441 | <p>You can use an Android-powered device as the runtime environment for |
| 442 | debugging and testing licensing on your application.</p> |
| 443 | |
| 444 | <p>The device you use must:</p> |
| 445 | |
| 446 | <ul> |
| 447 | <li>Run a standard version of the Android 1.5 or later (API level |
| 448 | 3 or higher) platform, <em>and</em> </li> |
| 449 | <li>Run a system image on which the Android Market client application |
| 450 | is preinstalled. </li> |
| 451 | </ul> |
| 452 | |
| 453 | <p>If Android Market is not preinstalled in the system image, your application won't |
| 454 | be able to communicate with the Android Market licensing server. </p> |
| 455 | |
| 456 | <p>For general information about how to set up a device for use in developing |
| 457 | Android applications, see <a |
| 458 | href="{@docRoot}guide/developing/device.html">Developing on a Device</a>.</p> |
| 459 | |
| 460 | <h4 id="runtime-emulator">Running on an Android emulator</h4> |
| 461 | |
| 462 | <p>You can also use an Android emulator as your runtime |
| 463 | environment for debugging and testing licensing.</p> |
| 464 | |
| 465 | <p>Because the standard Android platforms provided in the Android SDK <em>do |
| 466 | not</em> include Android Market, you need to download the Google APIs Add-On |
| 467 | platform, API Level 8 (or higher), from the SDK repository. After downloading |
| 468 | the add-on, you need to create an AVD configuration that uses that system image. |
| 469 | </p> |
| 470 | |
| 471 | <p>The Google APIs Add-On does not include the full Android Market client. |
| 472 | However, it does provide: </p> |
| 473 | |
| 474 | <ul> |
| 475 | <li>An Android Market background service that implements the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 476 | ILicensingService remote interface, so that your application can |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 477 | send license checks over the network to the licensing server. </li> |
| 478 | <li>A set of underlying account services that let you add an a Google account on |
| 479 | the AVD and sign in using your publisher account or test account credentials. |
| 480 | Signing in using your publisher or test account enables you to debug and test |
| 481 | your application without having publish it. For more information see <a |
| 482 | href="#acct-signin">Signing in to an authorized account</a>, below.</li> |
| 483 | </ul> |
| 484 | |
| 485 | <p>Several versions of the add-on are available in the SDK repository, but only |
| 486 | <strong>Google APIs Add-On, API 8 (release 2) or higher</strong> version of the |
| 487 | add-on includes the necessary Android Market services. This means that you |
| 488 | cannot use Google APIs Add-On API 7 or lower as a runtime environment for |
| 489 | developing licensing on an emulator.</p> |
| 490 | |
| 491 | <div style="margin-bottom:2em;"> |
| 492 | |
| 493 | <img src="{@docRoot}images/licensing_gapis_8.png" style="text-align:left;margin-bottom:0;" /> |
| 494 | <div style="margin:0 2em;padding:0"><strong>Figure 3.</strong> Google APIs |
| 495 | Add-On, API 8 (release 2) or higher lets you debug and test your licensing |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 496 | implementation in an emulator.</div> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 497 | </div> |
| 498 | |
| 499 | <p>To set up an emulator for adding licensing to an application, follow |
| 500 | these steps: </p> |
| 501 | |
| 502 | <ol> |
| 503 | <li>Launch the Android SDK and AVD Manager. </li> |
| 504 | <li>In the <strong>Available Packages</strong> panel, select and download the |
| 505 | SDK component "Google APIs (Google Inc.) - API Level 8" (or higher) from the SDK |
| 506 | repository, as shown in the figure above. |
| 507 | <p>When the download is complete, use the Android SDK and AVD Manager to |
| 508 | create a new AVD based on that component, described next.</p></li> |
| 509 | <li>In the <strong>Virtual |
| 510 | Devices</strong> panel of the Android SDK and AVD Manager, click |
| 511 | <strong>New</strong> and set the configuration details for the new AVD. </li> |
| 512 | <li>In the dialog that appears, assign a descriptive name to the AVD and then |
| 513 | use the "Target" menu to choose the "Google APIs (Google Inc.) - API Level 8" as |
| 514 | the system image to run on the new AVD. Set the other configuration details as |
| 515 | needed and then click <strong>Create AVD</strong> to finish. The SDK tools |
| 516 | create the new AVD configuration, which then appears in the list of available |
| 517 | Android Virtual Devices.</li> |
| 518 | </ol> |
| 519 | |
| 520 | <p>If you are not familiar with AVDs or how to use them, see <a |
| Scott Main | 13033ea | 2011-02-15 13:18:30 -0800 | [diff] [blame] | 521 | href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a>.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 522 | |
| 523 | <h4 id="project-update">Updating your project configuration</h4> |
| 524 | |
| 525 | <p>After you set up a runtime environment that meets the requirements described |
| 526 | above — either on an actual device or on an emulator — make sure to |
| 527 | update your application project or build scripts as needed, so that your compiled |
| 528 | <code>.apk</code> files that use licensing are deployed into that environment. |
| 529 | In particular, if you are developing in Eclipse, make sure that you set up a |
| 530 | Run/Debug Configuration that targets the appropriate device or AVD. </p> |
| 531 | |
| 532 | <p>You do not need to make any changes to your application's |
| 533 | build configuration, provided that the project is already configured to compile |
| 534 | against a standard Android 1.5 (API level 3) or higher library. For example: |
| 535 | |
| 536 | <ul> |
| 537 | <li>If you have an existing application that is compiled against |
| 538 | the Android 1.5 library, you do not need to make any changes to your |
| 539 | build configuration to support licensing. The build target meets the minimum |
| 540 | requirements for licensing, so you would continue building |
| 541 | against the same version of the Android platform.</li> |
| 542 | |
| 543 | <li>Similarly, if you are building against Android 1.5 (API level 3) but |
| 544 | are using an emulator running the Google APIs Add-On API 8 as the application's |
| 545 | runtime environment, there is no need to change your application's build |
| 546 | configuration. </li> |
| 547 | </ul> |
| 548 | |
| 549 | <p>In general, adding licensing to an application should have no impact |
| 550 | whatsoever on the application's build configuration.</p> |
| 551 | |
| 552 | |
| 553 | <h3 id="download-lvl">Downloading the LVL</h3> |
| 554 | |
| 555 | <p>The License Verification Library (LVL) is a collection of helper classes that |
| 556 | greatly simplify the work that you need to do to add licensing to your |
| 557 | application. In all cases, we recommend that you download the LVL and use it as |
| 558 | the basis for the licensing implementation in your application.</p> |
| 559 | |
| 560 | <p>The LVL is available as a downloadable component of the Android SDK. The |
| 561 | component includes: </p> |
| 562 | |
| 563 | <ul> |
| 564 | <li>The LVL sources, stored inside an Android library project. </li> |
| 565 | <li>An example application called "sample" that depends on the LVL library |
| 566 | project. The example illustrates how an application uses the library helper |
| 567 | classes to check and enforce licensing.</li> |
| 568 | </ul> |
| 569 | |
| 570 | <p>To download the LVL component into your development environment, use the |
| 571 | Android SDK and AVD Manager. Launch the Android SDK and AVD Manager and then |
| 572 | select the "Market Licensing" component, as shown in the figure below. |
| 573 | Accept the terms and click <strong>Install Selected</strong> to begin the download. </p> |
| 574 | |
| 575 | <div style="margin-bottom:2em;"> |
| 576 | |
| 577 | <img src="{@docRoot}images/licensing_package.png" style="text-align:left;margin-bottom:0;" /> |
| 578 | <div style="margin:0 2em;padding:0"><strong>Figure 4.</strong> The Market |
| 579 | Licensing package contains the LVL and the LVL sample application. </div> |
| 580 | </div> |
| 581 | |
| 582 | <p>When the download is complete, the Android SDK and AVD Manager installs both |
| 583 | the LVL library project and the example application into these directories: </p> |
| 584 | |
| Bill Gruber | 9a693ed | 2011-04-08 17:55:17 -0700 | [diff] [blame] | 585 | <p style="margin-left:2em"><code><<em>sdk</em>>/extras/google/market_licensing/library/</code> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 586 | (the LVL library project)<br /> |
| Bill Gruber | 9a693ed | 2011-04-08 17:55:17 -0700 | [diff] [blame] | 587 | <code><<em>sdk</em>>/extras/google/market_licensing/sample/</code> (the example |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 588 | application)</p> |
| 589 | |
| 590 | <p>If you aren't familiar with how to download components into your SDK, see the |
| 591 | <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a> |
| 592 | document. </p> |
| 593 | |
| 594 | |
| 595 | <h3 id="lvl-setup">Setting Up the Licensing Verification Library</h3> |
| 596 | |
| 597 | <p>After downloading the LVL to your computer, you need to set it up in your |
| 598 | development environment, either as an Android library project or by |
| 599 | copying (or importing) the library sources directly into your existing |
| 600 | application package. In general, using the LVL as a library project is recommended, |
| 601 | since it lets you reuse your licensing code across multiple applications and |
| 602 | maintain it more easily over time. Note that the LVL is not designed to be |
| 603 | compiled separately and added to an application as a static .jar file. </p> |
| 604 | |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 605 | <h4>Moving the library sources to a new location</h4> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 606 | |
| 607 | <p>Because you will be customizing the LVL sources to some extent, you should |
| 608 | make sure to <em>move or copy</em> the library sources (the entire |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 609 | directory at <code><<em>sdk</em>>/market_licensing/library/</code>) |
| 610 | to a working directory outside of the SDK. You should then use the relocated |
| 611 | sources as your working set. If you are using a source-code management |
| 612 | system, add and track the sources that are in the working location rather |
| 613 | than those in default location in the SDK. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 614 | |
| 615 | <p>Moving the library sources is important is because, when you later update the |
| 616 | Market licensing package, the SDK installs the new files to the same location as |
| 617 | the older files. Moving your working library files to a safe location ensures |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 618 | that your work won't be inadvertently overwritten should you download a new |
| 619 | version of the LVL.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 620 | |
| 621 | <h4>Creating the LVL as a library project</h4> |
| 622 | |
| 623 | <div class="sidebox-wrapper"> |
| 624 | <div class="sidebox"> |
| 625 | <h2>Working with library projects</h2> |
| 626 | |
| 627 | <p>The LVL is provided as an Android library project, which means that you can |
| 628 | share its code and resources across multiple applications. </p> |
| 629 | |
| 630 | <p style="margin-top:.5em;">If you aren't familiar with library projects or how |
| Robert Ly | c74a69a8 | 2011-01-04 22:48:02 -0800 | [diff] [blame] | 631 | to use them, see <a href="{@docRoot}guide/developing/projects/index.html#LibraryProjects"> |
| Scott Main | 13033ea | 2011-02-15 13:18:30 -0800 | [diff] [blame] | 632 | Managing Projects</a>. |
| Robert Ly | c74a69a8 | 2011-01-04 22:48:02 -0800 | [diff] [blame] | 633 | </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 634 | </div> |
| 635 | </div> |
| 636 | |
| 637 | <p>The recommended way of using the LVL is setting it up as a new Android |
| 638 | <em>library project</em>. A library project is a type of development project |
| 639 | that holds shared Android source code and resources. Other Android application |
| 640 | projects can reference the library project and, at build time, include its |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 641 | compiled sources in their <code>.apk</code> files. In the context of licensing, |
| 642 | this means that you can do most of your licensing development once, in a library |
| 643 | project, then include the library sources in your various application projects. |
| 644 | In this way, you can easily maintain a uniform implementation of licensing |
| 645 | across all of your projects and maintain it centrally. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 646 | |
| 647 | <p>The LVL is provided as a configured library project — once you have |
| 648 | downloaded it, you can start using it right away. </p> |
| 649 | |
| 650 | <p>If you are working in Eclipse with ADT, you need to add the LVL to your |
| 651 | workspace as a new development project, in the same way as you would a new |
| 652 | application project. </p> |
| 653 | |
| 654 | <ol> |
| 655 | <li>Use the New Project Wizard to create a new |
| 656 | project from existing sources. Select the LVL's <code>library</code> directory |
| 657 | (the directory containing the library's AndroidManifest.xml file) as the project |
| 658 | root.</li> |
| 659 | <li>When you are creating the library project, you can select any application |
| 660 | name, package, and set other fields as needed. </li> |
| 661 | <li>For the library's build target, select Android 1.5 (API level 3) or higher.</li> |
| 662 | </ol> |
| 663 | |
| 664 | <p> When created, the project is |
| 665 | predefined as a library project in its <code>default.properties</code> file, so |
| 666 | no further configuration is needed. </p> |
| 667 | |
| 668 | <p>For more information about how to create an application project or work with |
| Scott Main | 13033ea | 2011-02-15 13:18:30 -0800 | [diff] [blame] | 669 | library projects in Eclipse, see <a |
| 670 | href="{@docRoot}guide/developing/projects/projects-eclipse.html">Managing Projects from |
| 671 | Eclipse with ADT</a></p>. |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 672 | |
| 673 | <h4>Copying the LVL sources to your application</h4> |
| 674 | |
| 675 | <p>As an alternative to adding the LVL as a library project, you can copy the |
| 676 | library sources directly into your application. To do so, copy (or import) the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 677 | LVL's <code>library/src/com</code> directory into your application's |
| 678 | <code>src/</code> directory.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 679 | |
| 680 | <p>If you add the LVL sources directly to your application, you can skip the |
| 681 | next section and start working with the library, as described in <a |
| 682 | href="#app-integration"></a>.</p> |
| 683 | |
| 684 | |
| 685 | <h3 id="add-library">Including the LVL library project sources in your |
| 686 | application</h3> |
| 687 | |
| 688 | <p>If you want to use the LVL sources as a library project, you need to add a |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 689 | reference to the LVL library project in your application project properties. This tells |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 690 | build tools to include the LVL library project sources in your application at |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 691 | compile time. The process for adding a reference to a library project depends |
| 692 | on your development environment, as described below.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 693 | |
| 694 | <p> If you are developing in Eclipse with ADT, you should already have added the |
| 695 | library project to your workspace, as described in the previous section. If you |
| 696 | haven't done that already, do it now before continuing. </p> |
| 697 | |
| 698 | <p>Next, open the application's project properties window, as shown below. |
| 699 | Select the "Android" properties group and click <strong>Add</strong>, then |
| 700 | choose the LVL library project (com_android_vending_licensing) and click |
| Robert Ly | c74a69a8 | 2011-01-04 22:48:02 -0800 | [diff] [blame] | 701 | <strong>OK</strong>. For more information, see |
| Scott Main | 13033ea | 2011-02-15 13:18:30 -0800 | [diff] [blame] | 702 | <a href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject"> |
| 703 | Managing Projects from Eclipse with ADT</a></p>. |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 704 | |
| 705 | <div style="margin-bottom:2em;"> |
| 706 | |
| 707 | <img src="{@docRoot}images/licensing_add_library.png" style="text-align:left;margin-bottom:0;" /> |
| 708 | <div style="margin:0 2em;padding:0"><strong>Figure 5.</strong> If you are |
| 709 | working in Eclipse with ADT, you can add the LVL library project to your |
| 710 | application from the application's project properties.</div> |
| 711 | </div> |
| 712 | |
| 713 | <p>If you are developing using the SDK command-line tools, navigate to the |
| 714 | directory containing your application project and open the |
| 715 | <code>default.properties</code> file. Add a line to the file that specifies the |
| 716 | <code>android.library.reference.<n></code> key and the path to the |
| 717 | library. For example: </p> |
| 718 | |
| 719 | <pre>android.library.reference.1=path/to/library_project</pre> |
| 720 | |
| 721 | <p>Alternatively, you can use this command to update the project |
| 722 | properties, including the reference to the library project:</p> |
| 723 | |
| 724 | <pre class="no-pretty-print" style="color:black">android update lib-project |
| 725 | --target <em><target_ID></em> \ |
| 726 | --path <em>path/to/my/app_project</em> \ |
| 727 | --library <em>path/to/my/library_project</em> |
| 728 | </pre> |
| 729 | |
| Robert Ly | c74a69a8 | 2011-01-04 22:48:02 -0800 | [diff] [blame] | 730 | <p>For more information about working with library projects, |
| Scott Main | 13033ea | 2011-02-15 13:18:30 -0800 | [diff] [blame] | 731 | see <a href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject"> |
| 732 | Managing Projects from the Command Line</a></p>. |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 733 | |
| 734 | |
| 735 | <h2 id="app-integration">Integrating the LVL with Your Application</h2> |
| 736 | |
| 737 | <p>Once you've followed the steps above to set up a publisher account and |
| 738 | development environment, you are ready to begin integrating the LVL with your |
| 739 | application. </p> |
| 740 | |
| 741 | <p>Integrating the LVL with your application code involves these tasks:</p> |
| 742 | |
| 743 | <ol> |
| 744 | <li><a href="#manifest-permission">Adding the licensing permission</a> your application's manifest.</li> |
| 745 | <li><a href="#impl-Policy">Implementing a Policy</a> — you can choose one of the full implementations provided in the LVL or create your own.</li> |
| 746 | <li><a href="#impl-Obfuscator">Implementing an Obfuscator</a>, if your Policy will cache any license response data. </li> |
| 747 | <li><a href="#impl-lc">Adding code to check the license</a> in your application's main Activity</li> |
| 748 | <li><a href="#impl-DeviceLimiter">Implementing a DeviceLimiter</a> (optional and not recommended for most applications)</li> |
| 749 | </ol> |
| 750 | |
| 751 | <p>The sections below describe these tasks. When you are done with the |
| 752 | integration, you should be able to compile your application successfully and you |
| 753 | can begin testing, as described in <a href="#test-env">Setting Up the Test |
| 754 | Environment</a>.</p> |
| 755 | |
| 756 | <p>For an overview of the full set of source files included in the LVL, see <a |
| 757 | href="#lvl-summary">Summary of LVL Classes and Interfaces</a>.</p> |
| 758 | |
| 759 | |
| 760 | <h3 id="manifest-permission">Adding the licensing permission to your |
| 761 | AndroidManifest.xml</h3> |
| 762 | |
| 763 | <p>To use the Android Market application for sending a license check to the |
| 764 | server, your application must request the proper permission, |
| 765 | <code>com.android.vending.CHECK_LICENSE</code>. If your application does |
| 766 | not declare the licensing permission but attempts to initiate a license check, |
| 767 | the LVL throws a security exception.</p> |
| 768 | |
| 769 | <p>To request the licensing permission in your application, declare a <a |
| 770 | href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><code><uses-permission></code></a> |
| 771 | element as a child of <code><manifest></code>, as follows: </p> |
| 772 | |
| 773 | <p style="margin-left:2em;"><code><uses-permission |
| 774 | android:name="com.android.vending.CHECK_LICENSE"></code></p> |
| 775 | |
| 776 | <p>For example, here's how the LVL sample application declares the permission: |
| 777 | </p> |
| 778 | |
| 779 | <pre><?xml version="1.0" encoding="utf-8"?> |
| 780 | |
| 781 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" ..."> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 782 | <!-- Devices >= 3 have version of Android Market that supports licensing. --> |
| 783 | <uses-sdk android:minSdkVersion="3" /> |
| 784 | <!-- Required permission to check licensing. --> |
| 785 | <uses-permission android:name="com.android.vending.CHECK_LICENSE" /> |
| 786 | ... |
| 787 | </manifest> |
| 788 | </pre> |
| 789 | |
| 790 | <p class="note"><strong>Note:</strong> Currently, you cannot declare the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 791 | <code>CHECK_LICENSE</code> permission in the LVL library project's manifest, |
| 792 | because the SDK Tools will not merge it into the manifests of dependent |
| 793 | applications. Instead, you must declare the permission in each dependent |
| 794 | application's manifest. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 795 | |
| 796 | |
| 797 | <h3 id="impl-Policy">Implementing a Policy</h3> |
| 798 | |
| 799 | <div class="sidebox-wrapper"> |
| 800 | <div class="sidebox"> |
| 801 | <h2>ServerManagedPolicy</h2> |
| 802 | |
| 803 | <p>The LVL includes a complete Policy implementation called ServerManagedPolicy |
| 804 | that makes use of license-management settings provided by the Android Market |
| 805 | server. </p> |
| 806 | |
| 807 | <p style="margin-top:.5em;">Use of ServerManagedPolicy as the basis for your |
| 808 | Policy is strongly recommended. For more information, see <a |
| 809 | href="#ServerManagedPolicy">ServerManagedPolicy</a> section, below.</p> |
| 810 | |
| 811 | </div> |
| 812 | </div> |
| 813 | |
| 814 | <p>Android Market licensing service does not itself determine whether a |
| 815 | given user with a given license should be granted access to your application. |
| 816 | Rather, that responsibility is left to a Policy implementation that you provide |
| 817 | in your application.</p> |
| 818 | |
| 819 | <p>Policy is an interface declared by the LVL that is designed to hold your |
| 820 | application's logic for allowing or disallowing user access, based on the result |
| 821 | of a license check. To use the LVL, your application <em>must</em> provide an |
| 822 | implementation of Policy. </p> |
| 823 | |
| 824 | <p>The Policy interface declares two methods, <code>allowAccess()</code> and |
| 825 | <code>processServerResponse()</code>, which are called by a LicenseChecker |
| 826 | instance when processing a response from the license server. It also declares an |
| 827 | enum called <code>LicenseResponse</code>, which specifies the license response |
| 828 | value passed in calls to <code>processServerResponse()</code>. </p> |
| 829 | |
| 830 | <ul> |
| 831 | <li><code>processServerResponse()</code> lets you preprocess the raw response |
| 832 | data received from the licensing server, prior to determining whether to grant |
| 833 | access. |
| 834 | |
| 835 | <p>A typical implementation would extract some or all fields from the license |
| 836 | response and store the data locally to a persistent store, such as through |
| 837 | {@link android.content.SharedPreferences} storage, to ensure that the data is |
| 838 | accessible across application invocations and device power cycles. For example, |
| 839 | a Policy would maintain the timestamp of last successful license check, the |
| 840 | retry count, the license validity period, and similar information in a |
| 841 | persistent store, rather than resetting the values each time the application is |
| 842 | launched.</p> |
| 843 | |
| 844 | <p>When storing response data locally, the Policy must ensure that the data is |
| 845 | obfuscated (see <a href="#impl-Obfuscator">Implementing an Obfuscator</a>, |
| 846 | below).</p></li> |
| 847 | |
| 848 | <li><code>allowAccess()</code> determines whether to grant the user access to |
| 849 | your application, based on any available license response data (from the |
| 850 | licensing server or from cache) or other application-specific information. For |
| 851 | example, your implementation of <code>allowAccess()</code> could take into |
| 852 | account additional criteria, such as usage or other data retrieved from a |
| 853 | backend server. In all cases, an implementation of <code>allowAccess()</code> |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 854 | should only return <code>true</code> if the user is licensed to use the |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 855 | application, as determined by the licensing server, or if there is a transient |
| 856 | network or system problem that prevents the license check from completing. In |
| 857 | such cases, your implementation can maintain a count of retry responses and |
| 858 | provisionally allow access until the next license check is complete.</li> |
| 859 | |
| 860 | </ul> |
| 861 | |
| 862 | <p>To simplify the process of adding licensing to your application and to |
| 863 | provide an illustration of how a Policy should be designed, the LVL includes |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 864 | two full Policy implementations that you can use without modification or |
| 865 | adapt to your needs:</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 866 | |
| 867 | <ul> |
| 868 | <li><a href="#ServerManagedPolicy">ServerManagedPolicy</a>, a flexible Policy |
| 869 | that uses server-provided settings and cached responses to manage access across |
| 870 | varied network conditions, and</li> |
| 871 | <li><a href="#StrictPolicy">StrictPolicy</a>, which does not cache any response |
| 872 | data and allows access <em>only</em> if the server returns a licensed |
| 873 | response.</li> |
| 874 | </ul> |
| 875 | |
| 876 | <p>For most applications, the use of ServerManagedPolicy is highly |
| 877 | recommended. ServerManagedPolicy is the LVL default and is integrated with |
| 878 | the LVL sample application.</p> |
| 879 | |
| 880 | |
| 881 | <h4 id="custom-policies">Guidelines for custom policies</h4> |
| 882 | |
| 883 | <p>In your licensing implementation, you can use one of the complete policies |
| 884 | provided in the LVL (ServerManagedPolicy or StrictPolicy) or you can create a |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 885 | custom policy. For any type of custom policy, there are several important design |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 886 | points to understand and account for in your implementation.</p> |
| 887 | |
| 888 | <p>The licensing server applies general request limits to guard against overuse |
| 889 | of resources that could result in denial of service. When an application exceeds |
| 890 | the request limit, the licensing server returns a 503 response, which gets |
| 891 | passed through to your application as a general server error. This means that no |
| 892 | license response will be available to the user until the limit is reset, which |
| 893 | can affect the user for an indefinite period.</p> |
| 894 | |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 895 | <p>If you are designing a custom policy, we recommend that the Policy: |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 896 | <ol> |
| 897 | <!-- <li>Limits the number of points at which your app calls for a license check |
| 898 | to the minimum. </li> --> |
| 899 | <li>Caches (and properly obfuscates) the most recent successful license response |
| 900 | in local persistent storage.</li> |
| 901 | <li>Returns the cached response for all license checks, for as long as the |
| 902 | cached response is valid, rather than making a request to the licensing server. |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 903 | Setting the response validity according to the server-provided <code>VT</code> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 904 | extra is highly recommended. See <a href="#extras">Server Response Extras</a> |
| 905 | for more information.</li> |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 906 | <li>Uses an exponential backoff period, if retrying any requests the result in |
| 907 | errors. Note that the Android Market client automatically retries failed |
| 908 | requests, so in most cases there is no need for your Policy to retry them.</li> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 909 | <li>Provides for a "grace period" that allows the user to access your |
| 910 | application for a limited time or number of uses, while a license check is being |
| 911 | retried. The grace period benefits the user by allowing access until the next |
| 912 | license check can be completed successfully and it benefits you by placing a |
| 913 | hard limit on access to your application when there is no valid license response |
| 914 | available.</li> |
| 915 | </ol> |
| 916 | |
| 917 | <p>Designing your Policy according to the guidelines listed above is critical, |
| 918 | because it ensures the best possible experience for users while giving you |
| 919 | effective control over your application even in error conditions. </p> |
| 920 | |
| 921 | <p>Note that any Policy can use settings provided by the licensing server to |
| 922 | help manage validity and caching, retry grace period, and more. Extracting the |
| 923 | server-provided settings is straightforward and making use of them is highly |
| 924 | recommended. See the ServerManagedPolicy implementation for an example of how to |
| 925 | extract and use the extras. For a list of server settings and information about |
| 926 | how to use them, see <a href="#extras">Server Response Extras</a> in the |
| 927 | Appendix of this document.</p> |
| 928 | |
| 929 | <h4 id="ServerManagedPolicy">ServerManagedPolicy</h4> |
| 930 | |
| 931 | <div class="sidebox-wrapper"> |
| 932 | <div class="sidebox"> |
| 933 | <h2>Server Response Extras</h2> |
| 934 | |
| 935 | <p>For certain types of licensing responses, the licensing server appends extra |
| 936 | settings to the responses, to help the application manage licensing effectively. |
| 937 | </p> |
| 938 | |
| 939 | <p style="margin-top:.5em;">See <a href="#extras">Server Response Extras</a> for |
| 940 | a list of settings and <code>ServerManagedPolicy.java</code> for information |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 941 | about how a Policy can use the extras.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 942 | |
| 943 | </div> |
| 944 | </div> |
| 945 | |
| 946 | <p>The LVL includes a full and recommended implementation of the Policy |
| 947 | interface called ServerManagedPolicy. The implementation is integrated with the |
| 948 | LVL classes and serves as the default Policy in the library. </p> |
| 949 | |
| 950 | <p>ServerManagedPolicy provides all of the handling for license and retry |
| 951 | responses. It caches all of the response data locally in a |
| 952 | {@link android.content.SharedPreferences} file, obfuscating it with the |
| 953 | application's Obfuscator implementation. This ensures that the license response |
| 954 | data is secure and persists across device power cycles. ServerManagedPolicy |
| 955 | provides concrete implementations of the interface methods |
| 956 | <code>processServerResponse()</code> and <code>allowAccess()</code> and also |
| 957 | includes a set of supporting methods and types for managing license |
| 958 | responses.</p> |
| 959 | |
| 960 | <p>Importantly, a key feature of ServerMangedPolicy is its use of |
| 961 | server-provided settings as the basis for managing licensing across an |
| 962 | application's refund period and through varying network and error conditions. |
| 963 | When an application contacts the Android Market server for a license check, the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 964 | server appends several settings as key-value pairs in the extras field of certain |
| 965 | license response types. For example, the server provides recommended values for the |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 966 | application's license validity period, retry grace period, and maximum allowable |
| 967 | retry count, among others. ServerManagedPolicy extracts the values from the |
| 968 | license response in its <code>processServerResponse()</code> method and checks |
| 969 | them in its <code>allowAccess()</code> method. For a list of the server-provided |
| 970 | settings used by ServerManagedPolicy, see <a href="#extras">Server Response |
| 971 | Extras</a> in the Appendix of this document.</p> |
| 972 | |
| 973 | <p>For convenience, best performance, and the benefit of using license settings |
| 974 | from the Android Market server, <strong>using ServerManagedPolicy as your |
| 975 | licensing Policy is strongly recommended</strong>. </p> |
| 976 | |
| 977 | <p>If you are concerned about the security of license response data that is |
| 978 | stored locally in SharedPreferences, you can use a stronger obfuscation |
| 979 | algorithm or design a stricter Policy that does not store license data. The LVL |
| 980 | includes an example of such a Policy — see <a |
| 981 | href="#StrictPolicy">StrictPolicy</a> for more information.</p> |
| 982 | |
| 983 | <p>To use ServerManagedPolicy, simply import it to your Activity, create an |
| 984 | instance, and pass a reference to the instance when constructing your |
| 985 | LicenseChecker. See <a href="#lc-lcc">Instantiate LicenseChecker and |
| 986 | LicenseCheckerCallback</a> for more information. </p> |
| 987 | |
| 988 | <h4 id="StrictPolicy">StrictPolicy</h4> |
| 989 | |
| 990 | <p>The LVL includes an alternative full implementation of the Policy interface |
| 991 | called StrictPolicy. The StrictPolicy implementation provides a more restrictive |
| 992 | Policy than ServerManagedPolicy, in that it does not allow the user to access |
| 993 | the application unless a license response is received from the server at the |
| 994 | time of access that indicates that the user is licensed.</p> |
| 995 | |
| 996 | <p>The principal feature of StrictPolicy is that it does not store <em>any</em> |
| 997 | license response data locally, in a persistent store. Because no data is stored, |
| 998 | retry requests are not tracked and cached responses can not be used to fulfill |
| 999 | license checks. The Policy allows access only if:</p> |
| 1000 | |
| 1001 | <ul> |
| 1002 | <li>The license response is received from the licensing server, and </li> |
| 1003 | <li>The license response indicates that the user is licensed to access the |
| 1004 | application. </li> |
| 1005 | </ul> |
| 1006 | |
| 1007 | <p>Using StrictPolicy is appropriate if your primary concern is to ensure that, |
| 1008 | in all possible cases, no user will be allowed to access the application unless |
| 1009 | the user is confirmed to be licensed at the time of use. Additionally, the |
| 1010 | Policy offers slightly more security than ServerManagedPolicy — since |
| 1011 | there is no data cached locally, there is no way a malicious user could tamper |
| 1012 | with the cached data and obtain access to the application.</p> |
| 1013 | |
| 1014 | <p>At the same time, this Policy presents a challenge for normal users, since it |
| 1015 | means that they won't be able to access the application when there is no network |
| 1016 | (cell or wi-fi) connection available. Another side-effect is that your |
| 1017 | application will send more license check requests to the server, since using a |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1018 | cached response is not possible.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1019 | |
| 1020 | <p>Overall, this policy represents a tradeoff of some degree of user convenience |
| 1021 | for absolute security and control over access. Consider the tradeoff carefully |
| 1022 | before using this Policy.</p> |
| 1023 | |
| 1024 | <p>To use StrictPolicy, simply import it to your Activity, create an instance, |
| 1025 | and pass a reference to it when constructing your LicenseChecker. See |
| 1026 | <a href="#lc-lcc">Instantiate LicenseChecker and LicenseCheckerCallback</a> |
| 1027 | for more information. </p> |
| 1028 | |
| 1029 | <h3 id="impl-Obfuscator">Implementing an Obfuscator</h3> |
| 1030 | |
| 1031 | <div class="sidebox-wrapper"> |
| 1032 | <div class="sidebox"> |
| 1033 | <h2>AESObfuscator</h2> |
| 1034 | |
| 1035 | <p>The LVL includes a full Obfuscator implementation in the |
| 1036 | <code>AESObfuscator.java</code> file. The Obfuscator uses AES encryption to |
| 1037 | obfuscate/unobfuscate data. If you are using a Policy (such as |
| 1038 | ServerManagedPolicy) that caches license response data, using AESObfuscator as |
| 1039 | basis for your Obfuscator implementation is highly recommended. </p> |
| 1040 | |
| 1041 | </div> |
| 1042 | </div> |
| 1043 | |
| 1044 | <p>A typical Policy implementation needs to save the license response data for |
| 1045 | an application to a persistent store, so that it is accessible across |
| 1046 | application invocations and device power cycles. For example, a Policy would |
| 1047 | maintain the timestamp of the last successful license check, the retry count, |
| 1048 | the license validity period, and similar information in a persistent store, |
| 1049 | rather than resetting the values each time the application is launched. The |
| 1050 | default Policy included in the LVL, ServerManagedPolicy, stores license response |
| 1051 | data in a {@link android.content.SharedPreferences} instance, to ensure that the |
| 1052 | data is persistent. </p> |
| 1053 | |
| 1054 | <p>Because the Policy will use stored license response data to determine whether |
| 1055 | to allow or disallow access to the application, it <em>must</em> ensure that any |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1056 | stored data is secure and cannot be reused or manipulated by a root user on a |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1057 | device. Specifically, the Policy must always obfuscate the data before storing |
| 1058 | it, using a key that is unique for the application and device. Obfuscating using |
| 1059 | a key that is both application-specific and device-specific is critical, because |
| 1060 | it prevents the obfuscated data from being shared among applications and |
| 1061 | devices.</p> |
| 1062 | |
| 1063 | <p>The LVL assists the application with storing its license response data in a |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1064 | secure, persistent manner. First, it provides an Obfuscator |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1065 | interface that lets your application supply the obfuscation algorithm of its |
| 1066 | choice for stored data. Building on that, the LVL provides the helper class |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1067 | PreferenceObfuscator, which handles most of the work of calling the |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1068 | application's Obfuscator class and reading and writing the obfuscated data in a |
| 1069 | SharedPreferences instance. </p> |
| 1070 | |
| 1071 | <p>The LVL provides a full Obfuscator implementation called |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1072 | AESObfuscator that uses AES encryption to obfuscate data. You can |
| 1073 | use AESObfuscator in your application without modification or you |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1074 | can adapt it to your needs. For more information, see the next section.</p> |
| 1075 | |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1076 | |
| 1077 | <h4 id="AESObfuscator">AESObfuscator</h4> |
| 1078 | |
| 1079 | <p>The LVL includes a full and recommended implementation of the Obfuscator |
| 1080 | interface called AESObfuscator. The implementation is integrated with the |
| 1081 | LVL sample application and serves as the default Obfuscator in the library. </p> |
| 1082 | |
| 1083 | <p>AESObfuscator provides secure obfuscation of data by using AES to |
| 1084 | encrypt and decrypt the data as it is written to or read from storage. |
| 1085 | The Obfuscator seeds the encryption using three data fields provided |
| 1086 | by the application: </p> |
| 1087 | |
| 1088 | <ol> |
| 1089 | <li>A salt — an array of random bytes to use for each (un)obfuscation. </li> |
| 1090 | <li>An application identifier string, typically the package name of the application.</li> |
| 1091 | <li>A device identifier string, derived from as many device-specific sources |
| 1092 | as possible, so as to make it as unique.</li> |
| 1093 | </ol> |
| 1094 | |
| 1095 | <p>To use AESObfuscator, first import it to your Activity. Declare a private |
| 1096 | static final array to hold the salt bytes and initialize it to 20 randomly |
| 1097 | generated bytes.</p> |
| 1098 | |
| 1099 | <pre> ... |
| 1100 | // Generate 20 random bytes, and put them here. |
| 1101 | private static final byte[] SALT = new byte[] { |
| 1102 | -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95, |
| 1103 | -45, 77, -117, -36, -113, -11, 32, -64, 89 |
| 1104 | }; |
| 1105 | ... |
| 1106 | </pre> |
| 1107 | |
| 1108 | <p>Next, declare a variable to hold a device identifier and generate a value for |
| 1109 | it in any way needed. For example, the sample application included in the LVL |
| 1110 | queries the system settings for the |
| 1111 | <code>android.Settings.Secure.ANDROID_ID</code>, which is unique to each device. |
| 1112 | </p> |
| 1113 | |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1114 | <p>Note that, depending on the APIs you use, your application might need to |
| 1115 | request additional permissions in order to acquire device-specific information. |
| 1116 | For example, to query the {@link android.telephony.TelephonyManager} to obtain |
| 1117 | the device IMEI or related data, the application will also need to request the |
| 1118 | <code>android.permission.READ_PHONE_STATE</code> permission in its manifest.</p> |
| 1119 | |
| 1120 | <p>Before requesting new permissions for the <em>sole purpose</em> of acquiring |
| 1121 | device-specific information for use in your Obfuscator, consider |
| 1122 | how doing so might affect your application or its filtering on Android Market |
| 1123 | (since some permissions can cause the SDK build tools to add |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1124 | the associated <code><uses-feature></code>).</p> |
| 1125 | |
| 1126 | <p>Finally, construct an instance of AESObfuscator, passing the salt, |
| 1127 | application identifier, and device identifier. You can construct the instance |
| 1128 | directly, while constructing your Policy and LicenseChecker. For example:</p> |
| 1129 | |
| 1130 | <pre> ... |
| 1131 | // Construct the LicenseChecker with a Policy. |
| 1132 | mChecker = new LicenseChecker( |
| 1133 | this, new ServerManagedPolicy(this, |
| 1134 | new AESObfuscator(SALT, getPackageName(), deviceId)), |
| 1135 | BASE64_PUBLIC_KEY // Your public licensing key. |
| 1136 | ); |
| 1137 | ... |
| 1138 | </pre> |
| 1139 | |
| 1140 | <p>For a complete example, see MainActivity in the LVL sample application.</p> |
| 1141 | |
| 1142 | |
| 1143 | <h3 id="impl-lc">Checking the license from your application's main Activity</h3> |
| 1144 | |
| 1145 | <p>Once you've implemented a Policy for managing access to your application, the |
| 1146 | next step is to add a license check to your application, which initiates a query |
| 1147 | to the licensing server if needed and manages access to the application based on |
| 1148 | the license response. All of the work of adding the license check and handling |
| 1149 | the response takes place in your main {@link android.app.Activity} source file. |
| 1150 | </p> |
| 1151 | |
| 1152 | <p>To add the license check and handle the response, you must:</p> |
| 1153 | |
| 1154 | <ol> |
| 1155 | <li><a href="#imports">Add imports</a></li> |
| 1156 | <li><a href="#lc-impl">Implement LicenseCheckerCallback</a> as a private inner class</li> |
| 1157 | <li><a href="#thread-handler">Create a Handler</a> for posting from LicenseCheckerCallback to the UI thread</li> |
| 1158 | <li><a href="#lc-lcc">Instantiate LicenseChecker</a> and LicenseCheckerCallback</li> |
| 1159 | <li><a href="#check-access">Call checkAccess()</a> to initiate the license check</li> |
| 1160 | <li><a href="#account-key">Embed your public key</a> for licensing</li> |
| 1161 | <li><a href="#handler-cleanup">Call your LicenseChecker's onDestroy() method</a> to close IPC connections.</li> |
| 1162 | </ol> |
| 1163 | |
| 1164 | <p>The sections below describe these tasks. </p> |
| 1165 | |
| 1166 | <h4 id="lc-overview">Overview of license check and response</h4> |
| 1167 | |
| 1168 | <div class="sidebox-wrapper"> |
| 1169 | <div class="sidebox"> |
| 1170 | <h2>Example: MainActivity</h2> |
| 1171 | |
| 1172 | <p>The sample application included with the LVL provides a full example of how |
| 1173 | to initiate a license check and handle the result, in the |
| 1174 | <code>MainActivity.java</code> file.</p> |
| 1175 | |
| 1176 | </div> |
| 1177 | </div> |
| 1178 | |
| 1179 | <p>In most cases, you should add the license check to your application's main |
| 1180 | {@link android.app.Activity}, in the <code>onCreate()</code> method. This |
| 1181 | ensures that when the user launches your application directly, the license check |
| 1182 | will be invoked immediately. In some cases, you can add license checks in other |
| 1183 | locations as well. For example, if your application includes multiple Activity |
| 1184 | components that other applications can start by {@link android.content.Intent}, |
| 1185 | you could add license checks in those Activities.</p> |
| 1186 | |
| 1187 | <p>A license check consists of two main actions: </p> |
| 1188 | |
| 1189 | <ul> |
| 1190 | <li>A call to a method to initiate the license check — in the LVL, this is |
| 1191 | a call to the <code>checkAccess()</code> method of a LicenseChecker object that |
| 1192 | you construct.</li> |
| 1193 | <li>A callback that returns the result of the license check. In the LVL, this is |
| 1194 | a <code>LicenseCheckerCallback</code> interface that you implement. The |
| 1195 | interface declares two methods, <code>allow()</code> and |
| 1196 | <code>dontAllow()</code>, which are invoked by the library based on to the |
| 1197 | result of the license check. You implement those two methods with whatever logic |
| 1198 | you need, to allow or disallow the user access to your application. Note that |
| 1199 | these methods do not determine <em>whether</em> to allow access — that |
| 1200 | determination is the responsibility of your Policy implementation. Rather, these |
| 1201 | methods simply provide the application behaviors for <em>how</em> to allow and |
| 1202 | disallow access (and handle application errors).</li> |
| 1203 | </ul> |
| 1204 | |
| 1205 | <div style="margin-bottom:2em;"> |
| 1206 | |
| 1207 | <img src="{@docRoot}images/licensing_flow.png" style="text-align:left;margin-bottom:0;margin-left:3em;" /> |
| 1208 | <div style="margin:.5em 0 1.5em 2em;padding:0"><strong>Figure 6.</strong> Overview of a |
| 1209 | typical license check interaction.</div> |
| 1210 | </div> |
| 1211 | |
| 1212 | <p>The diagram above illustrates how a typical license check takes place: </p> |
| 1213 | |
| 1214 | <ol> |
| 1215 | <li>Code in the application's main Activity instantiates LicenseCheckerCallback |
| 1216 | and LicenseChecker objects. When constructing LicenseChecker, the code passes in |
| 1217 | {@link android.content.Context}, a Policy implementation to use, and the |
| 1218 | publisher account's public key for licensing as parameters. </li> |
| 1219 | <li>The code then calls the <code>checkAccess()</code> method on the |
| 1220 | LicenseChecker object. The method implementation calls the Policy to determine |
| 1221 | whether there is a valid license response cached locally, in |
| 1222 | {@link android.content.SharedPreferences}. |
| 1223 | <ul> |
| 1224 | <li>If so, the <code>checkAccess()</code> implementation calls |
| 1225 | <code>allow()</code>.</li> |
| 1226 | <li>Otherwise, the LicenseChecker initiates a license check request that is sent |
| 1227 | to the licensing server.</li> |
| 1228 | </ul> |
| 1229 | </li> |
| 1230 | <li>When a response is received, LicenseChecker creates a LicenseValidator that |
| 1231 | verifies the signed license data and extracts the fields of the response, then |
| 1232 | passes them to your Policy for further evaluation. |
| 1233 | <ul> |
| 1234 | <li>If the license is valid, the Policy caches the response in |
| 1235 | SharedPreferences and notifies the validator, which then calls the |
| 1236 | <code>allow()</code> method on the LicenseCheckerCallback object. </li> |
| 1237 | <li>If the license not valid, the Policy notifies the validator, which calls |
| 1238 | the <code>dontAllow()</code> method on LicenseCheckerCallback. </li> |
| 1239 | </ul> |
| 1240 | </li> |
| 1241 | <li>In case of a recoverable local or server error, such as when the network is |
| 1242 | not available to send the request, LicenseChecker passes a RETRY response to |
| 1243 | your Policy's <code>processServerResponse()</code> method. </li> |
| 1244 | <li>In case of a application error, such as when the application attempts to |
| 1245 | check the license of an invalid package name, LicenseChecker passes an error |
| 1246 | response to the LicenseCheckerCallback's <code>applicationError()</code> |
| 1247 | method. </li> |
| 1248 | </ol> |
| 1249 | |
| 1250 | <p>Note that, in addition to initiating the license check and handling the |
| 1251 | result, which are described in the sections below, your application also needs |
| 1252 | to provide a <a href="#impl-Policy">Policy implementation</a> and, if the Policy |
| 1253 | stores response data (such as ServerManagedPolicy), an <a |
| 1254 | href="#impl-Obfuscator">Obfuscator</a> implementation. </p> |
| 1255 | |
| 1256 | |
| 1257 | <h4 id="imports">Add imports</h4> |
| 1258 | |
| 1259 | <p>First, open the class file of the application's main Activity and import |
| 1260 | LicenseChecker and LicenseCheckerCallback from the LVL package.</p> |
| 1261 | |
| 1262 | <pre> import com.android.vending.licensing.LicenseChecker; |
| 1263 | import com.android.vending.licensing.LicenseCheckerCallback;</pre> |
| 1264 | |
| 1265 | <p>If you are using the default Policy implementation provided with the LVL, |
| 1266 | ServerManagedPolicy, import it also, together with the AESObfuscator. If you are |
| 1267 | using a custom Policy or Obfuscator, import those instead. </p> |
| 1268 | |
| 1269 | <pre> import com.android.vending.licensing.ServerManagedPolicy; |
| 1270 | import com.android.vending.licensing.AESObfuscator;</pre> |
| 1271 | |
| 1272 | <h4 id="lc-impl">Implement LicenseCheckerCallback as a private inner class</h4> |
| 1273 | |
| 1274 | <p>LicenseCheckerCallback is an interface provided by the LVL for handling |
| 1275 | result of a license check. To support licensing using the LVL, you must |
| 1276 | implement LicenseCheckerCallback and |
| 1277 | its methods to allow or disallow access to the application.</p> |
| 1278 | |
| 1279 | <p>The result of a license check is always a call to one of the |
| 1280 | LicenseCheckerCallback methods, made based on the validation of the response |
| 1281 | payload, the server response code itself, and any additional processing provided |
| 1282 | by your Policy. Your application can implement the methods in any way needed. In |
| 1283 | general, it's best to keep the methods simple, limiting them to managing UI |
| 1284 | state and application access. If you want to add further processing of license |
| 1285 | responses, such as by contacting a backend server or applying custom constraints, |
| 1286 | you should consider incorporating that code into your Policy, rather than |
| 1287 | putting it in the LicenseCheckerCallback methods. </p> |
| 1288 | |
| 1289 | <p>In most cases, you should declare your implementation of |
| 1290 | LicenseCheckerCallback as a private class inside your application's main |
| 1291 | Activity class. </p> |
| 1292 | |
| 1293 | <p>Implement the <code>allow()</code> and <code>dontAllow()</code> methods as |
| 1294 | needed. To start with, you can use simple result-handling behaviors in the |
| 1295 | methods, such as displaying the license result in a dialog. This helps you get |
| 1296 | your application running sooner and can assist with debugging. Later, after you |
| 1297 | have determined the exact behaviors you want, you can add more complex handling. |
| 1298 | </p> |
| 1299 | |
| 1300 | <p>Some suggestions for handling unlicensed responses in |
| 1301 | <code>dontAllow()</code> include: </p> |
| 1302 | |
| 1303 | <ul> |
| 1304 | <li>Display a "Try again" dialog to the user, including a button to initiate a |
| 1305 | new license check. </li> |
| 1306 | <li>Display a "Purchase this application" dialog, including a button that |
| 1307 | deep-links the user to the application's details page on Market, from which the |
| 1308 | use can purchase the application. For more information on how to set up such |
| 1309 | links, see <a |
| 1310 | href="{@docRoot}guide/publishing/publishing.html#marketintent">Using Intents to |
| 1311 | Launch the Market Application on a Device</a>. </li> |
| 1312 | <li>Display a Toast notification that indicates that the features of the |
| 1313 | application are limited because it is not licensed. </li> |
| 1314 | </ul> |
| 1315 | |
| 1316 | <p>The example below shows how the LVL sample application implements |
| 1317 | LicenseCheckerCallback, with methods that display the license check result in a |
| 1318 | dialog. </p> |
| 1319 | |
| 1320 | <pre> private class MyLicenseCheckerCallback implements LicenseCheckerCallback { |
| 1321 | public void allow() { |
| 1322 | if (isFinishing()) { |
| 1323 | // Don't update UI if Activity is finishing. |
| 1324 | return; |
| 1325 | } |
| 1326 | // Should allow user access. |
| 1327 | displayResult(getString(R.string.allow)); |
| 1328 | } |
| 1329 | |
| 1330 | public void dontAllow() { |
| 1331 | if (isFinishing()) { |
| 1332 | // Don't update UI if Activity is finishing. |
| 1333 | return; |
| 1334 | } |
| 1335 | displayResult(getString(R.string.dont_allow)); |
| 1336 | // Should not allow access. An app can handle as needed, |
| 1337 | // typically by informing the user that the app is not licensed |
| 1338 | // and then shutting down the app or limiting the user to a |
| 1339 | // restricted set of features. |
| 1340 | // In this example, we show a dialog that takes the user to Market. |
| 1341 | showDialog(0); |
| 1342 | } |
| 1343 | } |
| 1344 | </pre> |
| 1345 | |
| 1346 | <p>Additionally, you should implement the <code>applicationError()</code> |
| 1347 | method, which the LVL calls to let your application handle errors that are not |
| 1348 | retryable. For a list of such errors, see <a |
| 1349 | href="#server-response-codes">Server Response Codes</a> in the Appendix of this |
| 1350 | document. You can implement the method in any way needed. In most cases, the |
| 1351 | method should log the error code and call <code>dontAllow()</code>.</p> |
| 1352 | |
| 1353 | <h4 id="thread-handler">Create a Handler for posting from LicenseCheckerCallback |
| 1354 | to the UI thread</h4> |
| 1355 | |
| 1356 | <p>During a license check, the LVL passes the request to the Android Market |
| 1357 | application, which handles communication with the licensing server. The LVL |
| 1358 | passes the request over asynchronous IPC (using {@link android.os.Binder}) so |
| 1359 | the actual processing and network communication do not take place on a thread |
| 1360 | managed by your application. Similarly, when the Android Market application |
| 1361 | receives the result, it invokes a callback method over IPC, which in turn |
| 1362 | executes in an IPC thread pool in your application's process.</p> |
| 1363 | |
| 1364 | <p>The LicenseChecker class manages your application's IPC communication with |
| 1365 | the Android Market application, including the call that sends the request and |
| 1366 | the callback that receives the response. LicenseChecker also tracks open license |
| 1367 | requests and manages their timeouts. </p> |
| 1368 | |
| 1369 | <p>So that it can handle timeouts properly and also process incoming responses |
| 1370 | without affecting your application's UI thread, LicenseChecker spawns a |
| 1371 | background thread at instantiation. In the thread it does all processing of |
| 1372 | license check results, whether the result is a response received from the server |
| 1373 | or a timeout error. At the conclusion of processing, the LVL calls your |
| 1374 | LicenseCheckerCallback methods from the background thread. </p> |
| 1375 | |
| 1376 | <p>To your application, this means that:</p> |
| 1377 | |
| 1378 | <ol> |
| 1379 | <li>Your LicenseCheckerCallback methods will be invoked, in many cases, from a |
| 1380 | background thread.</li> |
| 1381 | <li>Those methods won't be able to update state or invoke any processing in the |
| 1382 | UI thread, unless you create a Handler in the UI thread and have your callback |
| 1383 | methods post to the Handler.</li> |
| 1384 | </ol> |
| 1385 | |
| 1386 | <p>If you want your LicenseCheckerCallback methods to update the UI thread, |
| 1387 | instantiate a {@link android.os.Handler} in the main Activity's |
| 1388 | {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method, |
| 1389 | as shown below. In this example, the LVL sample application's |
| 1390 | LicenseCheckerCallback methods (see above) call <code>displayResult()</code> to |
| 1391 | update the UI thread through the Handler's |
| 1392 | {@link android.os.Handler#post(java.lang.Runnable) post()} method.</p> |
| 1393 | |
| 1394 | <pre>private Handler mHandler; |
| 1395 | |
| 1396 | @Override |
| 1397 | public void onCreate(Bundle savedInstanceState) { |
| 1398 | ... |
| 1399 | mHandler = new Handler(); |
| 1400 | } |
| 1401 | </pre> |
| 1402 | |
| 1403 | <p>Then, in your LicenseCheckerCallback methods, you can use Handler methods to |
| 1404 | post Runnable or Message objects to the Handler. Here's how the sample |
| 1405 | application included in the LVL posts a Runnable to a Handler in the UI thread |
| 1406 | to display the license status.</p> |
| 1407 | |
| 1408 | <pre> private void displayResult(final String result) { |
| 1409 | mHandler.post(new Runnable() { |
| 1410 | public void run() { |
| 1411 | mStatusText.setText(result); |
| 1412 | setProgressBarIndeterminateVisibility(false); |
| 1413 | mCheckLicenseButton.setEnabled(true); |
| 1414 | } |
| 1415 | }); |
| 1416 | } |
| 1417 | </pre> |
| 1418 | |
| 1419 | <h4 id="lc-lcc">Instantiate LicenseChecker and LicenseCheckerCallback</h4> |
| 1420 | |
| 1421 | <p>In the main Activity's |
| 1422 | {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method, |
| 1423 | create private instances of LicenseCheckerCallback and LicenseChecker. You must |
| 1424 | instantiate LicenseCheckerCallback first, because you need to pass a reference |
| 1425 | to that instance when you call the contructor for LicenseChecker. </p> |
| 1426 | |
| 1427 | <p>When you instantiate LicenseChecker, you need to pass in these parameters:</p> |
| 1428 | |
| 1429 | <ul> |
| 1430 | <li>The application {@link android.content.Context}</li> |
| 1431 | <li>A reference to the Policy implementation to use for the license check. In |
| 1432 | most cases, you would use the default Policy implementation provided by the LVL, |
| 1433 | ServerManagedPolicy. </li> |
| 1434 | <li>The String variable holding your publisher account's public key for |
| 1435 | licensing. </li> |
| 1436 | </ul> |
| 1437 | |
| 1438 | <p>If you are using ServerManagedPolicy, you won't need to access the class |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1439 | directly, so you can instantiate it in the LicenseChecker constructor, |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1440 | as shown in the example below. Note that you need to pass a reference to a new |
| 1441 | Obfuscator instance when you construct ServerManagedPolicy.</p> |
| 1442 | |
| 1443 | <p>The example below shows the instantiation of LicenseChecker and |
| 1444 | LicenseCheckerCallback from the <code>onCreate()</code> method of an Activity |
| 1445 | class. </p> |
| 1446 | |
| 1447 | <pre>public class MainActivity extends Activity { |
| 1448 | ... |
| 1449 | private LicenseCheckerCallback mLicenseCheckerCallback; |
| 1450 | private LicenseChecker mChecker; |
| 1451 | |
| 1452 | @Override |
| 1453 | public void onCreate(Bundle savedInstanceState) { |
| 1454 | super.onCreate(savedInstanceState); |
| 1455 | ... |
| 1456 | // Construct the LicenseCheckerCallback. The library calls this when done. |
| 1457 | mLicenseCheckerCallback = new MyLicenseCheckerCallback(); |
| 1458 | |
| 1459 | // Construct the LicenseChecker with a Policy. |
| 1460 | mChecker = new LicenseChecker( |
| 1461 | this, new ServerManagedPolicy(this, |
| 1462 | new AESObfuscator(SALT, getPackageName(), deviceId)), |
| 1463 | BASE64_PUBLIC_KEY // Your public licensing key. |
| 1464 | ); |
| 1465 | ... |
| 1466 | } |
| 1467 | } |
| 1468 | </pre> |
| 1469 | |
| 1470 | |
| 1471 | <p>Note that LicenseChecker calls the LicenseCheckerCallback methods from the UI |
| 1472 | thread <em>only</em> if there is valid license response cached locally. If the |
| 1473 | license check is sent to the server, the callbacks always originate from the |
| 1474 | background thread, even for network errors. </p> |
| 1475 | |
| 1476 | |
| 1477 | <h4 id="check-access">Call checkAccess() to initiate the license check</h4> |
| 1478 | |
| 1479 | <p>In your main Activity, add a call to the <code>checkAccess()</code> method of the |
| 1480 | LicenseChecker instance. In the call, pass a reference to your |
| 1481 | LicenseCheckerCallback instance as a parameter. If you need to handle any |
| 1482 | special UI effects or state management before the call, you might find it useful |
| 1483 | to call <code>checkAccess()</code> from a wrapper method. For example, the LVL |
| 1484 | sample application calls <code>checkAccess()</code> from a |
| 1485 | <code>doCheck()</code> wrapper method:</p> |
| 1486 | |
| 1487 | <pre> @Override |
| 1488 | public void onCreate(Bundle savedInstanceState) { |
| 1489 | super.onCreate(savedInstanceState); |
| 1490 | ... |
| 1491 | // Call a wrapper method that initiates the license check |
| 1492 | doCheck(); |
| 1493 | ... |
| 1494 | } |
| 1495 | ... |
| 1496 | private void doCheck() { |
| 1497 | mCheckLicenseButton.setEnabled(false); |
| 1498 | setProgressBarIndeterminateVisibility(true); |
| 1499 | mStatusText.setText(R.string.checking_license); |
| 1500 | mChecker.checkAccess(mLicenseCheckerCallback); |
| 1501 | } |
| 1502 | </pre> |
| 1503 | |
| 1504 | |
| 1505 | <h4 id="account-key">Embed your public key for licensing</h4> |
| 1506 | |
| 1507 | <p>For each publisher account, the Android Market service automatically |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1508 | generates a 2048-bit RSA public/private key pair that is used exclusively for |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1509 | licensing. The key pair is uniquely associated with the publisher account and is |
| 1510 | shared across all applications that are published through the account. Although |
| 1511 | associated with a publisher account, the key pair is <em>not</em> the same as |
| 1512 | the key that you use to sign your applications (or derived from it).</p> |
| 1513 | |
| 1514 | <p>The Android Market publisher site exposes the public key for licensing to any |
| 1515 | developer signed in to the publisher account, but it keeps the private key |
| 1516 | hidden from all users in a secure location. When an application requests a |
| 1517 | license check for an application published in your account, the licensing server |
| 1518 | signs the license response using the private key of your account's key pair. |
| 1519 | When the LVL receives the response, it uses the public key provided by the |
| 1520 | application to verify the signature of the license response. </p> |
| 1521 | |
| 1522 | <p>To add licensing to an application, you must obtain your publisher account's |
| 1523 | public key for licensing and copy it into your application. Here's how to find |
| 1524 | your account's public key for licensing:</p> |
| 1525 | |
| 1526 | <ol> |
| 1527 | <li>Go to the Android Market <a |
| 1528 | href="http://market.android.com/publish">publisher site</a> and sign in. |
| 1529 | Make sure that you sign in to the account from which the application you are |
| 1530 | licensing is published (or will be published). </li> |
| 1531 | <li>In the account home page, locate the "Edit profile" link and click it. </li> |
| 1532 | <li>In the Edit Profile page, locate the "Licensing" pane, shown below. Your |
| Bill Gruber | 9a693ed | 2011-04-08 17:55:17 -0700 | [diff] [blame] | 1533 | public key for licensing is given in the "Public key" text box. </li> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1534 | </ol> |
| 1535 | |
| 1536 | <p>To add the public key to your application, simply copy/paste the key string |
| 1537 | from the text box into your application as the value of the String variable |
| 1538 | <code>BASE64_PUBLIC_KEY</code>. When you are copying, make sure that you have |
| 1539 | selected the entire key string, without omitting any characters. </p> |
| 1540 | |
| 1541 | <p>Here's an example from the LVL sample application:</p> |
| 1542 | |
| 1543 | <pre> public class MainActivity extends Activity { |
| 1544 | private static final String BASE64_PUBLIC_KEY = "MIIBIjANBgkqhkiG ... "; //truncated for this example |
| 1545 | ... |
| 1546 | } |
| 1547 | </pre> |
| 1548 | |
| 1549 | <h4 id="handler-cleanup">Call your LicenseChecker's onDestroy() method |
| 1550 | to close IPC connections</h4> |
| 1551 | |
| 1552 | <p>Finally, to let the LVL clean up before your application |
| 1553 | {@link android.content.Context} changes, add a call to the LicenseChecker's |
| 1554 | <code>onDestroy()</code> method from your Activity's |
| 1555 | {@link android.app.Activity#onDestroy()} implementation. The call causes the |
| 1556 | LicenseChecker to properly close any open IPC connection to the Android Market |
| 1557 | application's ILicensingService and removes any local references to the service |
| 1558 | and handler.</p> |
| 1559 | |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1560 | <p>Failing to call the LicenseChecker's <code>onDestroy()</code> method |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1561 | can lead to problems over the lifecycle of your application. For example, if the |
| 1562 | user changes screen orientation while a license check is active, the application |
| 1563 | {@link android.content.Context} is destroyed. If your application does not |
| 1564 | properly close the LicenseChecker's IPC connection, your application will crash |
| 1565 | when the response is received. Similarly, if the user exits your application |
| 1566 | while a license check is in progress, your application will crash when the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1567 | response is received, unless it has properly called the |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1568 | LicenseChecker's <code>onDestroy()</code> method to disconnect from the service. |
| 1569 | </p> |
| 1570 | |
| 1571 | <p>Here's an example from the sample application included in the LVL, where |
| 1572 | <code>mChecker</code> is the LicenseChecker instance:</p> |
| 1573 | |
| 1574 | <pre> @Override |
| 1575 | protected void onDestroy() { |
| 1576 | super.onDestroy(); |
| 1577 | mChecker.onDestroy(); |
| 1578 | ... |
| 1579 | } |
| 1580 | </pre> |
| 1581 | |
| 1582 | <p>If you are extending or modifying LicenseChecker, you might also need to call |
| 1583 | the LicenseChecker's <code>finishCheck()</code> method, to clean up any open IPC |
| 1584 | connections.</p> |
| 1585 | |
| 1586 | <h3 id="impl-DeviceLimiter">Implementing a DeviceLimiter</h3> |
| 1587 | |
| 1588 | <p>In some cases, you might want your Policy to limit the number of actual |
| 1589 | devices that are permitted to use a single license. This would prevent a user |
| 1590 | from moving a licensed application onto a number of devices and using the |
| 1591 | application on those devices under the same account ID. It would also prevent a |
| 1592 | user from "sharing" the application by providing the account information |
| 1593 | associated with the license to other individuals, who could then sign in to that |
| 1594 | account on their devices and access the license to the application. </p> |
| 1595 | |
| 1596 | <p>The LVL supports per-device licensing by providing a |
| 1597 | <code>DeviceLimiter</code> interface, which declares a single method, |
| 1598 | <code>allowDeviceAccess()</code>. When a LicenseValidator is handling a response |
| 1599 | from the licensing server, it calls <code>allowDeviceAccess()</code>, passing a |
| 1600 | user ID string extracted from the response.</p> |
| 1601 | |
| 1602 | <p>If you do not want to support device limitation, <strong>no work is |
| 1603 | required</strong> — the LicenseChecker class automatically uses a default |
| 1604 | implementation called NullDeviceLimiter. As the name suggests, NullDeviceLimiter |
| 1605 | is a "no-op" class whose <code>allowDeviceAccess()</code> method simply returns |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1606 | a <code>LICENSED</code> response for all users and devices. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1607 | |
| 1608 | <div style="border-left:4px solid #FFCF00;margin:1em;padding: 0 0 0 .5em"> |
| 1609 | <p><strong>Caution:</strong> Per-device licensing is <em>not recommended for |
| 1610 | most applications</em> because:</p> |
| 1611 | <ul> |
| 1612 | <li>It requires that you provide a backend server to manage a users and devices |
| 1613 | mapping, and </li> |
| 1614 | <li>It could inadvertently result in a user being denied access to an |
| 1615 | application that they have legitimately purchased on another device.</li> |
| 1616 | </ul> |
| 1617 | </div> |
| 1618 | |
| 1619 | |
| 1620 | <h2 id="test-env">Setting Up the Testing Environment</h2> |
| 1621 | |
| 1622 | <p>The Android Market publisher site provides configuration tools that let you |
| 1623 | and others test licensing on your application before it is published. As you are |
| 1624 | implementing licensing, you can make use of the publisher site tools to test |
| 1625 | your application's Policy and handling of different licensing responses and |
| 1626 | error conditions.</p> |
| 1627 | |
| 1628 | <p>The main components of the test environment for licensing include: </p> |
| 1629 | |
| 1630 | <ul> |
| 1631 | <li>A "Test response" configuration in your publisher account that lets you |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1632 | set the static licensing response returned, when the server processes a |
| 1633 | license check for an application uploaded to the publisher account, from a user |
| 1634 | signed in to the publisher account or a test account.</li> |
| 1635 | <li>An optional set of test accounts that will receive the static test |
| 1636 | response when they check the license of an application that you have uploaded |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1637 | (regardless whether the application is published or not).</li> |
| 1638 | <li>A runtime environment for the application that includes the Android Market |
| 1639 | application or Google APIs Add-On, on which the user is signed in to the |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1640 | publisher account or one of the test accounts.</li> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1641 | </ul> |
| 1642 | |
| 1643 | <p>Setting up the test environment properly involves:</p> |
| 1644 | |
| 1645 | <ol> |
| 1646 | <li><a href="#test-response">Setting static test responses</a> that are returned by the licensing server.</li> |
| 1647 | <li><a href="#test-acct-setup">Setting up test accounts</a> as needed.</li> |
| 1648 | <li><a href="#acct-signin">Signing in</a> properly to an emulator or device, before initiating a license check test.</li> |
| 1649 | </ol> |
| 1650 | |
| 1651 | <p>The sections below provide more information.</p> |
| 1652 | |
| 1653 | |
| 1654 | <h3 id="test-response">Setting test responses for license checks</h3> |
| 1655 | |
| 1656 | <p>Android Market provides a configuration setting in your publisher account |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1657 | that lets you override the normal processing of a license check and return a |
| 1658 | specified static response code. The setting is for testing only and applies |
| 1659 | <em>only</em> to license checks for applications that you have uploaded, made by |
| 1660 | any user signed in to an emulator or device using the credentials of the |
| 1661 | publisher account or a registered test account. For other users, the server |
| 1662 | always processes license checks according to normal rules. </p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1663 | |
| 1664 | <p>To set a test response for your account, sign in to your publisher account |
| 1665 | and click "Edit Profile". In the Edit Profile page, locate the Test Response |
| 1666 | menu in the Licensing panel, shown below. You can select from the full set of |
| 1667 | valid server response codes to control the response or condition you want to |
| 1668 | test in your application.</p> |
| 1669 | |
| 1670 | <p>In general, you should make sure to test your application's licensing |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1671 | implementation with every response code available in the Test Response menu. |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1672 | For a description of the codes, see <a href="#server-response-codes">Server |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1673 | Response Codes</a> in the Appendix of this document.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1674 | |
| 1675 | <div style="margin-bottom:2em;" id="licensing_test_response"> |
| 1676 | |
| 1677 | <img src="{@docRoot}images/licensing_test_response.png" style="text-align:left;margin-bottom:0;" /> |
| 1678 | <div style="margin:0 2em;padding:0"><strong>Figure 7.</strong> The Licensing |
| 1679 | panel of your account's Edit Profile page, showing the Test Accounts field and the |
| 1680 | Test Response menu.</div> |
| 1681 | </div> |
| 1682 | |
| 1683 | <p>Note that the test response that you configure applies account-wide — |
| 1684 | that is, it applies not to a single application, but to <em>all</em> |
| 1685 | applications associated with the publisher account. If you are testing multiple |
| 1686 | applications at once, changing the test response will affect all of those |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1687 | applications on their next license check (if the user is signed into |
| 1688 | the emulator or device using the publisher account or a test account).</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1689 | |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1690 | <p>Before you can successfully receive a test response for a license check, |
| 1691 | you must sign in to the device or emulator on which the application |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1692 | is installed, and from which it is querying the server. Specifically, you must |
| 1693 | sign using either your publisher account or one of the test accounts that you |
| 1694 | have set up. For more information about test accounts, see the next section.</p> |
| 1695 | |
| 1696 | <p>See <a href="#server-response-codes">Server Response Codes</a> for a list of |
| 1697 | test responses available and their meanings. </p> |
| 1698 | |
| 1699 | |
| 1700 | <h3 id="test-acct-setup">Setting up test accounts</h3> |
| 1701 | |
| 1702 | <p>In some cases, you might want to let multiple teams of developers test |
| 1703 | licensing on applications that will ultimately be published through your |
| 1704 | publisher account, but without giving them access to your publisher account's |
| 1705 | sign-in credentials. To meet that need, the Android Market publisher site lets |
| 1706 | you set up one or more optional <em>test accounts</em> — accounts that are |
| 1707 | authorized to query the licensing server and receive static test responses from |
| 1708 | your publisher account.</p> |
| 1709 | |
| 1710 | <p>Test accounts are standard Google accounts that you register on your |
| 1711 | publisher account, such that they will receive the test response for |
| 1712 | applications that you have uploaded. Developers can then sign in to their |
| 1713 | devices or emulators using the test account credentials and initiate license |
| 1714 | checks from installed applications. When the licensing server receives a license |
| 1715 | check from a user of a test account, it returns the static test response |
| 1716 | configured for the publisher account. </p> |
| 1717 | |
| 1718 | <p>Necessarily, there are limitations on the access and permissions given to |
| 1719 | users signed in through test accounts, including:</p> |
| 1720 | |
| 1721 | <ul> |
| 1722 | <li>Test account users can query the licensing server only for applications that |
| 1723 | are already uploaded to the publisher account. </li> |
| 1724 | <li>Test account users do not have permission to upload applications to your |
| 1725 | publisher account.</li> |
| 1726 | <li>Test account users do not have permission to set the publisher account's |
| 1727 | static test response.</li> |
| 1728 | </ul> |
| 1729 | |
| 1730 | <p>The table below summarizes the differences in capabilities, between the |
| 1731 | publisher account, a test account, and any other account.</p> |
| 1732 | |
| 1733 | <p class="table-caption" id="acct-types-table"><strong>Table 1.</strong> |
| 1734 | Differences in account types for testing licensing.</p> |
| 1735 | |
| 1736 | <table> |
| 1737 | <tr> |
| 1738 | <th>Account Type</th> |
| 1739 | <th>Can check license before upload?</th> |
| 1740 | <th>Can receive test response?</th> |
| 1741 | <th>Can set test response?</th> |
| 1742 | </tr> |
| 1743 | |
| 1744 | <tr> |
| 1745 | <td>Publisher account</td> |
| 1746 | <td>Yes</td> |
| 1747 | <td>Yes</td> |
| 1748 | <td>Yes</td> |
| 1749 | </tr> |
| 1750 | |
| 1751 | <tr> |
| 1752 | <td>Test account</td> |
| 1753 | <td>No</td> |
| 1754 | <td>Yes</td> |
| 1755 | <td>No</td> |
| 1756 | </tr> |
| 1757 | |
| 1758 | <tr> |
| 1759 | <td>Other</td> |
| 1760 | <td>No</td> |
| 1761 | <td>No</td> |
| 1762 | <td>No</td> |
| 1763 | </tr> |
| 1764 | </table> |
| 1765 | |
| 1766 | <h4 id="reg-test-acct">Registering test accounts on the publisher account</h4> |
| 1767 | |
| 1768 | <p>To get started, you need to register each test account in your publisher |
| 1769 | account. As shown in <a href="#licensing_test_response">Figure 7</a>, above, you |
| 1770 | register test accounts in the Licensing panel of your publisher account's Edit |
| 1771 | Profile page. Simply enter the accounts as a comma-delimited list and click |
| 1772 | <strong>Save</strong> to save your profile changes.</p> |
| 1773 | |
| 1774 | <p>You can use any Google account as a test account. If you want to own and |
| 1775 | control the test accounts, you can create the accounts yourself and distribute |
| 1776 | the credentials to your developers or testers.</p> |
| 1777 | |
| 1778 | <h4 id="test-app-upload">Handling application upload and distribution for test |
| 1779 | account users</h4> |
| 1780 | |
| 1781 | <p>As mentioned above, users of test accounts can only receive static test |
| 1782 | responses for applications that are uploaded to the publisher account. Since |
| 1783 | those users do not have permission to upload applications, as the publisher you |
| 1784 | will need to work with those users to collect apps for upload and distribute |
| 1785 | uploaded apps for testing. You can handle collection and distribution in any way |
| 1786 | that is convenient. </p> |
| 1787 | |
| 1788 | <p>Once an application is uploaded and becomes known to the licensing server, |
| 1789 | developers and testers can continue modify the application in their local |
| 1790 | development environment, without having to upload new versions. You only need to |
| 1791 | upload a new version if the local application increments the |
| 1792 | <code>versionCode</code> attribute in the manifest file. </p> |
| 1793 | |
| 1794 | <h4 id="test-key">Distributing your public key to test account users</h4> |
| 1795 | |
| 1796 | <p>The licensing server handles static test responses in the normal way, |
| 1797 | including signing the license response data, adding extras parameters, and so |
| 1798 | on. To support developers who are implementing licensing using test accounts, |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 1799 | rather than the publisher account, you will need to distribute |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 1800 | your public key to them. Developers without access to the publisher site do not |
| 1801 | have access to your public key, and without the key they won't be able to |
| 1802 | verify license responses. </p> |
| 1803 | |
| 1804 | <p>Note that if you decide to generate a new licensing key pair for your account |
| 1805 | for some reason, you need to notify all users of test accounts. For |
| 1806 | testers, you can embed the new key in the application package and distribute it |
| 1807 | to users. For developers, you will need to distribute the new key to them |
| 1808 | directly. </p> |
| 1809 | |
| 1810 | |
| 1811 | <h3 id="acct-signin">Signing in to an authorized account in the runtime |
| 1812 | environment</h3> |
| 1813 | |
| 1814 | <p>The licensing service is designed to determine whether a given user is |
| 1815 | licensed to use a given application — during a license check, the Android |
| 1816 | Market application gathers the user ID from the primary account on the system |
| 1817 | and sends it to the server, together with the package name of the application |
| 1818 | and other information. However, if there is no user information available, the |
| 1819 | license check cannot succeed, so the Android Market application terminates the |
| 1820 | request and returns an error to the application. </p> |
| 1821 | |
| 1822 | <p>During testing, to ensure that your application can successfully query the |
| 1823 | licensing server, you must make sure that you sign in to an account <em>on the |
| 1824 | device or emulator</em> using:</p> |
| 1825 | |
| 1826 | <ul> |
| 1827 | <li>The credentials of a publisher account, or</li> |
| 1828 | <li>The credentials of a test account that is registered with a publisher |
| 1829 | account</li> |
| 1830 | </ul> |
| 1831 | |
| 1832 | |
| 1833 | <div class="sidebox-wrapper"> |
| 1834 | <div class="sidebox"> |
| 1835 | <h2>Signing in to a Google account on an emulator</h2> |
| 1836 | |
| 1837 | <p>If you are testing licensing on an emulator, you need to sign in to a Google |
| 1838 | account on the emulator. If you do not see an option to create a new Google |
| 1839 | account, the problem might be that your AVD is running a standard Android system |
| 1840 | image, rather than the Google APIs Add-On, API 8 (release 2) or higher. </p> |
| 1841 | |
| 1842 | <p style="margin-top:.5em;">For more information, see <a |
| 1843 | href="#runtime-setup">Setting up the runtime environment</a>, above.</p> |
| 1844 | |
| 1845 | </div> |
| 1846 | </div> |
| 1847 | |
| 1848 | <p>Signing in using a publisher account offers the advantage of letting your |
| 1849 | applications receive static test responses even before the applications are |
| 1850 | uploaded to the publisher site.</p> |
| 1851 | |
| 1852 | <p>If you are part of a larger organization or are working with external groups |
| 1853 | on applications that will be published through your site, you will more likely |
| 1854 | want to distribute test accounts instead, then use those to sign in during |
| 1855 | testing. </p> |
| 1856 | |
| 1857 | <p>To sign in on a device or emulator, follow the steps below. The preferred |
| 1858 | approach is to sign in as the primary account — however, if there are |
| 1859 | other accounts already in use on the device or emulator, you can create an |
| 1860 | additional account and sign in to it using the publisher or test account |
| 1861 | credentials. </p> |
| 1862 | |
| 1863 | <ol> |
| 1864 | <li>Open Settings > Accounts & sync</li> |
| 1865 | <li>Select <strong>Add Account</strong> and choose to add a "Google" account. |
| 1866 | </li> |
| 1867 | <li>Select <strong>Next</strong> and then <strong>Sign in</strong>.</li> |
| 1868 | <li>Enter the username and password of either the publisher account or a test |
| 1869 | account that is registered in the publisher account.</li> |
| 1870 | <li>Select <strong>Sign in</strong>. The system signs you in to the new |
| 1871 | account.</li> |
| 1872 | </ol> |
| 1873 | |
| 1874 | <p>Once you are signed in, you can begin testing licensing in your application |
| 1875 | (if you have completed the LVL integration steps above). When your application |
| 1876 | initiates a license check, it will receive a response containing the static test |
| 1877 | response configured on the publisher account. </p> |
| 1878 | |
| 1879 | <p>Note that, if you are using an emulator, you will need to sign in to the |
| 1880 | publisher account or test account each time you wipe data when restarting the |
| 1881 | emulator.</p> |
| 1882 | |
| 1883 | <div style="margin:2em 1em 1em 1em;"> |
| 1884 | |
| 1885 | <img src="{@docRoot}images/licensing_device_signin.png" style="text-align:left;" /> |
| 1886 | <div style="margin:.25em 1.25em;padding:0"><strong>Figure 8.</strong> Example of |
| 1887 | setting up a Google account on a device or emulator.</div> |
| 1888 | </div> |
| 1889 | |
| 1890 | <h2 id="app-obfuscation">Obfuscating Your Application</h2> |
| 1891 | |
| 1892 | <p>To ensure the security of your application, particularly for a paid |
| 1893 | application that uses licensing and/or custom constraints and protections, it's |
| 1894 | very important to obfuscate your application code. Properly obfuscating your |
| 1895 | code makes it more difficult for a malicious user to decompile the application's |
| 1896 | bytecode, modify it — such as by removing the license check — |
| 1897 | and then recompile it.</p> |
| 1898 | |
| 1899 | <p>Several obfuscator programs are available for Android applications, including |
| 1900 | <a href="http://proguard.sourceforge.net/">ProGuard</a>, which also offers |
| 1901 | code-optimization features. The use of ProGuard or a similar program to obfuscate |
| 1902 | your code is <em>strongly recommended</em> for all applications that use Android |
| 1903 | Market Licensing. </p> |
| 1904 | |
| 1905 | <h2 id="app-publishing">Publishing a Licensed Application</h2> |
| 1906 | |
| 1907 | <p>When you are finished testing your license implementation, you are ready to |
| 1908 | publish the application on Android Market. Follow the normal steps to <a |
| 1909 | href="{@docRoot}guide/publishing/preparing.html">prepare</a>, <a |
| 1910 | href="{@docRoot}guide/publishing/app-signing.html">sign</a>, and then <a |
| 1911 | href="{@docRoot}guide/publishing/publishing.html">publish the application</a>. |
| 1912 | </p> |
| 1913 | |
| 1914 | <h4>Removing Copy Protection</h4> |
| 1915 | |
| 1916 | <p>After uploading your licensed application, remember to remove copy protection |
| 1917 | from the application, if it is currently used. To check and remove copy |
| 1918 | protection, sign in to the publisher site and go the application's upload |
| 1919 | details page. In the Publishing options section, make sure that the Copy |
| 1920 | Protection radio button selection is "Off".</p> |
| 1921 | |
| 1922 | <h4>Considerations for Free Apps</h4> |
| 1923 | |
| 1924 | <p>Licensing is currently supported only for paid applications. If you already |
| 1925 | published your application as free, you won't be able to upload an updated |
| 1926 | version that includes licensing (that is, an application that uses the same |
| 1927 | package name and that includes the <a href="#manifest-permission">licensing |
| 1928 | permission</a>). Here are some points to keep in mind:</p> |
| 1929 | |
| 1930 | <ul> |
| 1931 | <li>If you want to offer a free version of your application that provides a |
| 1932 | reduced feature set (or that offers the full feature set for trial period), the |
| 1933 | free version of your application must not include the licensing permission and |
| 1934 | must use a different package name than the paid version of the app.</li> |
| 1935 | <li>If you want to offer a paid version of your free application that uses |
| 1936 | licensing, you can do so under a new package name.</li> |
| 1937 | </ul> |
| 1938 | |
| 1939 | <h2 id="support">Where to Get Support</h2> |
| 1940 | |
| 1941 | <p>If you have questions or encounter problems while implementing or deploying |
| 1942 | publishing in your applications, please use the support resources listed in the |
| 1943 | table below. By directing your queries to the correct forum, you can get the |
| 1944 | support you need more quickly. </p> |
| 1945 | |
| 1946 | <p class="table-caption"><strong>Table 2.</strong> Developer support resources |
| 1947 | for Android Market Licensing Service.</p> |
| 1948 | |
| 1949 | <table> |
| 1950 | |
| 1951 | <tr> |
| 1952 | <th>Support Type</th> |
| 1953 | <th>Resource</th> |
| 1954 | <th>Range of Topics</th> |
| 1955 | </tr> |
| 1956 | <tr> |
| 1957 | <td rowspan="2">Development and testing issues</td> |
| 1958 | <td>Google Groups: <a |
| 1959 | href="http://groups.google.com/group/android-developers">android-developers</a> |
| 1960 | </td> |
| 1961 | <td rowspan="2">LVL download and integration, library projects, Policy |
| 1962 | questions, user experience ideas, handling of responses, Obfuscator, IPC, test |
| 1963 | environment setup</td> |
| 1964 | </tr> |
| 1965 | <tr> |
| 1966 | <td>Stack Overflow: <a |
| 1967 | href="http://stackoverflow.com/questions/tagged/android">http://stackoverflow.com/questions/tagged/android</a></td> |
| 1968 | </tr> |
| 1969 | <tr> |
| 1970 | <td rowspan="2">Accounts, publishing, and deployment issues</td> |
| 1971 | <td><a href="http://www.google.com/support/forum/p/Android+Market">Android |
| 1972 | Market Help Forum</a></td> |
| 1973 | <td rowspan="2">Publisher accounts, licensing key pair, test accounts, server |
| 1974 | responses, test responses, application deployment and results</td> |
| 1975 | </tr> |
| 1976 | <tr> |
| 1977 | <td><a |
| 1978 | href="http://market.android.com/support/bin/answer.py?answer=186113">Market |
| 1979 | Licensing Support FAQ</a></td> |
| 1980 | </tr> |
| 1981 | <tr> |
| 1982 | <td>LVL issue tracker</td> |
| 1983 | <td><a href="http://code.google.com/p/marketlicensing/issues/">Marketlicensing |
| 1984 | project issue tracker</a></td> |
| 1985 | <td>Bug and issue reports related specifically to the LVL source code classes |
| 1986 | and interface implementations</td> |
| 1987 | </tr> |
| 1988 | |
| 1989 | </table> |
| 1990 | |
| 1991 | <p>For general information about how to post to the groups listed above, see <a |
| 1992 | href="{@docRoot}resources/community-groups.html">Developer Forums</a> document |
| 1993 | in the Resources tab.</p> |
| 1994 | |
| 1995 | <h2 id="lvl-summary">Summary of LVL Classes and Interfaces</h2> |
| 1996 | |
| 1997 | <p>The table below lists all of the source files in the License Verification |
| 1998 | Library (LVL) available through the Android SDK. All of the files are part of |
| 1999 | the <code>com.android.vending.licensing</code> package.</p> |
| 2000 | |
| 2001 | <p class="table-caption"><strong>Table A-1.</strong> Summary of LVL library |
| 2002 | classes and interfaces.</p> |
| 2003 | |
| 2004 | <div style="width:99%"> |
| 2005 | <table width="100%"> |
| 2006 | |
| 2007 | <tr> |
| 2008 | <th width="15%">Category</th> |
| 2009 | <th width="20%">Name</th> |
| 2010 | <th width="100%">Description</th> |
| 2011 | </tr> |
| 2012 | |
| 2013 | <tr> |
| 2014 | <td rowspan="2">License check and result</td> |
| 2015 | <td>LicenseChecker</td> |
| 2016 | <td>Class that you instantiate (or subclass) to initiate a license check.</td> |
| 2017 | </tr> |
| 2018 | <tr> |
| 2019 | <td><em>LicenseCheckerCallback</em></td> |
| 2020 | <td>Interface that you implement to handle result of the license check.</td> |
| 2021 | </tr> |
| 2022 | |
| 2023 | <tr> |
| 2024 | <td rowspan="3" width="15%">Policy</td> |
| 2025 | <td width="20%"><em>Policy</em></td> |
| 2026 | <td width="100%">Interface that you implement to determine whether to allow |
| 2027 | access to the application, based on the license response. </td> |
| 2028 | </tr> |
| 2029 | <tr> |
| 2030 | <td>ServerManagedPolicy</td> |
| 2031 | <td width="100%">Default Policy implementation. Uses settings provided by the |
| 2032 | licensing server to manage local storage of license data, license validity, |
| 2033 | retry.</td> |
| 2034 | </tr> |
| 2035 | <tr> |
| 2036 | <td>StrictPolicy</td> |
| 2037 | <td>Alternative Policy implementation. Enforces licensing based on a direct |
| 2038 | license response from the server only. No caching or request retry.</td> |
| 2039 | </tr> |
| 2040 | |
| 2041 | <tr> |
| 2042 | <td rowspan="2" width="15%">Data obfuscation <br><em>(optional)</em></td> |
| 2043 | <td width="20%"><em>Obfuscator</em></td> |
| 2044 | <td width="100%">Interface that you implement if you are using a Policy (such as |
| 2045 | ServerManagedPolicy) that caches license response data in a persistent store. |
| 2046 | Applies an obfuscation algorithm to encode and decode data being written or |
| 2047 | read.</td> |
| 2048 | </tr> |
| 2049 | <tr> |
| 2050 | <td>AESObfuscator</td> |
| 2051 | <td>Default Obfuscator implementation that uses AES encryption/decryption |
| 2052 | algorithm to obfuscate/unobfuscate data.</td> |
| 2053 | </tr> |
| 2054 | |
| 2055 | <tr> |
| 2056 | <td rowspan="2" width="15%">Device limitation<br><em>(optional)</em></td> |
| 2057 | <td width="20%"><em>DeviceLimiter</em></td> |
| 2058 | <td width="100%">Interface that you implement if you want to restrict use of an |
| 2059 | application to a specific device. Called from LicenseValidator. Implementing |
| 2060 | DeviceLimiter is not recommended for most applications because it requires a |
| 2061 | backend server and may cause the user to lose access to licensed applications, |
| 2062 | unless designed with care.</td> |
| 2063 | </tr> |
| 2064 | <tr> |
| 2065 | <td>NullDeviceLimiter</td> |
| 2066 | <td>Default DeviceLimiter implementation that is a no-op (allows access to all |
| 2067 | devices).</td> |
| 2068 | </tr> |
| 2069 | |
| 2070 | <tr> |
| 2071 | <td rowspan="6" width="15%">Library core, no integration needed</td> |
| 2072 | <td width="20%">ResponseData</td> |
| 2073 | <td width="100%">Class that holds the fields of a license response.</td> |
| 2074 | </tr> |
| 2075 | <tr> |
| 2076 | <td>LicenseValidator</td> |
| 2077 | <td>Class that decrypts and verifies a response received from the licensing |
| 2078 | server.</td> |
| 2079 | </tr> |
| 2080 | <tr> |
| 2081 | <td>ValidationException</td> |
| 2082 | <td>Class that indicates errors that occur when validating the integrity of data |
| 2083 | managed by an Obfuscator.</td> |
| 2084 | </tr> |
| 2085 | <tr> |
| 2086 | <td>PreferenceObfuscator</td> |
| 2087 | <td>Utility class that writes/reads obfuscated data to the system's |
| 2088 | {@link android.content.SharedPreferences} store.</td> |
| 2089 | </tr> |
| 2090 | <tr> |
| 2091 | <td><em>ILicensingService</em></td> |
| 2092 | <td>One-way IPC interface over which a license check request is passed to the |
| 2093 | Android Market client.</td> |
| 2094 | </tr> |
| 2095 | <tr> |
| 2096 | <td><em>ILicenseResultListener</em></td> |
| 2097 | <td>One-way IPC callback implementation over which the application receives an |
| 2098 | asynchronous response from the licensing server.</td> |
| 2099 | </tr> |
| 2100 | |
| 2101 | </table> |
| 2102 | </div> |
| 2103 | |
| 2104 | |
| 2105 | <h2 id="server-response-codes">Server Response Codes</h2> |
| 2106 | |
| 2107 | <p>The table below lists all of the license response codes supported by the |
| 2108 | licensing server. In general, an application should handle all of these response |
| 2109 | codes. By default, the LicenseValidator class in the LVL provides all of the |
| 2110 | necessary handling of these response codes for you. </p> |
| 2111 | |
| 2112 | <p class="table-caption"><strong>Table A-2.</strong> Summary of response codes |
| 2113 | returned by the Android Market server in a license response.</p> |
| 2114 | |
| 2115 | <table> |
| 2116 | |
| 2117 | <tr> |
| 2118 | <th>Response Code</th> |
| 2119 | <th>Description</th> |
| 2120 | <th>Signed?</th> |
| 2121 | <th>Extras</th> |
| 2122 | <th>Comments</th> |
| 2123 | </tr> |
| 2124 | <tr> |
| 2125 | <td>LICENSED</td> |
| 2126 | <td>The application is licensed to the user. The user has purchased the |
| Trevor Johns | 331c5f4 | 2011-02-04 15:00:02 -0800 | [diff] [blame] | 2127 | application or the application only exists as a draft.</td> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 2128 | <td>Yes</td> |
| 2129 | <td><code>VT</code>, <code>GT</code>, <code>GR</code></td> |
| 2130 | <td><em>Allow access according to Policy constraints.</em></td> |
| 2131 | </tr> |
| 2132 | <tr> |
| 2133 | <td>LICENSED_OLD_KEY</td> |
| 2134 | <td>The application is licensed to the user, but there is an updated application |
| 2135 | version available that is signed with a different key. </td> |
| 2136 | <td>Yes </td> |
| 2137 | <td><code>VT</code>, <code>GT</code>, <code>GR</code>, <code>UT</code></td> |
| 2138 | <td><em>Optionally allow access according to Policy constraints.</em> |
| 2139 | <p style="margin-top:.5em;">Can indicate that the key pair used by the installed |
| 2140 | application version is invalid or compromised. The application can allow access |
| 2141 | if needed or inform the user that an upgrade is available and limit further use |
| 2142 | until upgrade.</p> |
| 2143 | </td> |
| 2144 | </tr> |
| 2145 | <tr> |
| 2146 | <td>NOT_LICENSED</td> |
| 2147 | <td>The application is not licensed to the user.</td> |
| 2148 | <td>No</td> |
| 2149 | <td></td> |
| 2150 | <td><em>Do not allow access.</em></td> |
| 2151 | </tr> |
| 2152 | <tr> |
| 2153 | <td>ERROR_CONTACTING_SERVER</td> |
| 2154 | <td>Local error — the Android Market application was not able to reach the |
| 2155 | licensing server, possibly because of network availability problems. </td> |
| 2156 | <td>No</td> |
| 2157 | <td></td> |
| 2158 | <td><em>Retry the license check according to Policy retry limits.</em></td> |
| 2159 | </tr> |
| 2160 | <tr> |
| 2161 | <td>ERROR_SERVER_FAILURE</td> |
| 2162 | <td>Server error — the server could not load the publisher account's key |
| 2163 | pair for licensing.</td> |
| 2164 | <td>No</td> |
| 2165 | <td></td> |
| 2166 | <td><em>Retry the license check according to Policy retry limits.</em> |
| 2167 | </td> |
| 2168 | </tr> |
| 2169 | <tr> |
| 2170 | <td>ERROR_INVALID_PACKAGE_NAME</td> |
| 2171 | <td>Local error — the application requested a license check for a package |
| 2172 | that is not installed on the device. </td> |
| 2173 | <td>No </td> |
| 2174 | <td></td> |
| 2175 | <td><em>Do not retry the license check.</em> |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 2176 | <p style="margin-top:.5em;">Typically caused by a development error.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 2177 | </td> |
| 2178 | </tr> |
| 2179 | <tr> |
| 2180 | <td>ERROR_NON_MATCHING_UID</td> |
| 2181 | <td>Local error — the application requested a license check for a package |
| 2182 | whose UID (package, user ID pair) does not match that of the requesting |
| 2183 | application. </td> |
| 2184 | <td>No </td> |
| 2185 | <td></td> |
| 2186 | <td><em>Do not retry the license check.</em> |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 2187 | <p style="margin-top:.5em;">Typically caused by a development error.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 2188 | </td> |
| 2189 | </tr> |
| 2190 | <tr> |
| 2191 | <td>ERROR_NOT_MARKET_MANAGED</td> |
| 2192 | <td>Server error — the application (package name) was not recognized by |
| 2193 | Android Market. </td> |
| 2194 | <td>No</td> |
| 2195 | <td></td> |
| 2196 | <td><em>Do not retry the license check.</em> |
| 2197 | <p style="margin-top:.5em;">Can indicate that the application was not published |
| 2198 | through Android Market or that there is an development error in the licensing |
| 2199 | implementation.</p> |
| 2200 | </td> |
| 2201 | </tr> |
| 2202 | |
| 2203 | </table> |
| 2204 | |
| Trevor Johns | 331c5f4 | 2011-02-04 15:00:02 -0800 | [diff] [blame] | 2205 | <p class="note"><strong>Note:</strong> As documented in <a href="#test-env"> |
| 2206 | Setting Up The Testing Environment</a>, the response code can be manually |
| 2207 | overridden for the application developer and any registered test users via the |
| 2208 | Android Market publisher site. |
| 2209 | <br/><br/> |
| 2210 | Additionally, as noted above, applications that are in draft mode (in other |
| 2211 | words, applicaitons that have been uploaded but have <em>never</em> been |
| 2212 | published) will return LICENSED for all users, even if not listed as a test |
| 2213 | user. Since the application has never been offered for download, it is assumed |
| 2214 | that any users running it must have obtained it from an authorized channel for |
| 2215 | testing purposes.</p> |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 2216 | |
| 2217 | <h2 id="extras">Server Response Extras</h2> |
| 2218 | |
| 2219 | <p>The licensing server includes several settings in certain types of license |
| 2220 | responses, to assist the application and its Policy in managing access to the |
| 2221 | application across the 24-hour refund period and other conditions. Specifically, |
| 2222 | the server provides recommended values for the application's license validity |
| 2223 | period, retry grace period, maximum allowable retry count, and other settings. |
| 2224 | The server appends the settings as key-value pairs in the license response |
| 2225 | "extras" field. </p> |
| 2226 | |
| 2227 | <p>Any Policy implementation can extract the extras settings from the license |
| 2228 | response and use them as needed. The LVL default Policy implementation, <a |
| 2229 | href="#ServerManagedPolicy">ServerManagedPolicy</a>, serves as a working |
| 2230 | implementation and an illustration of how to obtain, store, and use the |
| 2231 | settings. </p> |
| 2232 | |
| 2233 | <p class="table-caption"><strong>Table A-3.</strong> Summary of |
| 2234 | license-management settings supplied by the Android Market server in a license |
| 2235 | response.</p> |
| 2236 | |
| 2237 | <table> |
| 2238 | <tr> |
| 2239 | <th>Extra</th><th>Description</th> |
| 2240 | </tr> |
| 2241 | |
| 2242 | <tr> |
| 2243 | <td>VT</td> |
| 2244 | <td>License validity timestamp. Specifies the date/time at which the current |
| 2245 | (cached) license response expires and must be rechecked on the licensing server. |
| 2246 | </td> |
| 2247 | </tr> |
| 2248 | <tr> |
| 2249 | <td>GT</td> |
| 2250 | <td>Grace period timestamp. Specifies the end of the period during which a |
| 2251 | Policy may allow access to the application, even though the response status is |
| 2252 | RETRY. <p>The value is managed by the server, however a typical value would be 5 |
| 2253 | or more days.</p></td> |
| 2254 | </tr> |
| 2255 | <tr> |
| 2256 | <td>GR</td> |
| 2257 | <td>Maximum retries count. Specifies how many consecutive RETRY license checks |
| 2258 | the Policy should allow, before denying the user access to the application. |
| 2259 | <p>The value is managed by the server, however a typical value would be "10" or |
| 2260 | higher.</p></td> |
| 2261 | </tr> |
| 2262 | <tr> |
| 2263 | <td>UT</td> |
| 2264 | <td>Update timestamp. Specifies the day/time when the most recent update to |
| 2265 | this application was uploaded and published. <p>The server returns this extra |
| 2266 | only for LICENSED_OLD_KEYS responses, to allow the Policy to determine how much |
| 2267 | time has elapsed since an update was published with new licensing keys before |
| 2268 | denying the user access to the application. </p></td> |
| 2269 | </tr> |
| 2270 | |
| 2271 | </table> |
| 2272 | |
| 2273 | <p>The sections below provide more information about the server-provided |
| 2274 | settings and how to use them. </p> |
| 2275 | |
| 2276 | <h4>License validity period</h4> |
| 2277 | |
| 2278 | <p>The Android Market licensing server sets a license validity period for all |
| 2279 | downloaded applications. The period expresses the interval of time over which an |
| 2280 | application's license status should be considered as unchanging and cacheable by |
| 2281 | a licensing Policy in the application. The licensing server includes the |
| 2282 | validity period in its response to all license checks, appending an |
| 2283 | end-of-validity timestamp to the response as an extra under the key "VT". A |
| 2284 | Policy can extract the VT key value and use it to conditionally allow access to |
| 2285 | the application without rechecking the license, until the validity period |
| 2286 | expires. </p> |
| 2287 | |
| 2288 | <p>The license validity signals to a licensing Policy when it must recheck the |
| 2289 | licensing status with the licensing server. It is <em>not</em> intended to imply |
| 2290 | whether an application is actually licensed for use. That is, when an |
| 2291 | application's license validity period expires, this does not mean that the |
| 2292 | application is no longer licensed for use — rather, it indicates only that |
| 2293 | the Policy must recheck the licensing status with the server. It follows that, |
| 2294 | as long as the license validity period is not expired, it is acceptable for the |
| 2295 | Policy to cache the initial license status locally and return the cached license |
| 2296 | status instead of sending a new license check to the server.</p> |
| 2297 | |
| 2298 | <p>The licensing server manages the validity period as a means of helping the |
| 2299 | application properly enforce licensing across the refund period offered by |
| 2300 | Android Market for paid applications. It sets the validity period based on |
| 2301 | whether the application was purchased and, if so, how long ago. Specifically, |
| 2302 | the server sets a validity period as follows:</p> |
| 2303 | |
| 2304 | <ul> |
| 2305 | <li>For a paid application, the server sets the initial license validity period |
| Dirk Dougherty | 2ff1ba0 | 2010-07-28 19:37:01 -0700 | [diff] [blame] | 2306 | so that the license response remains valid for as long as the application is |
| Dirk Dougherty | 0ac8ac3 | 2010-07-20 18:38:53 -0700 | [diff] [blame] | 2307 | refundable. A licensing Policy in the application may cache the |
| 2308 | result of the initial license check and does not need to recheck the license |
| 2309 | until the validity period has expired.</li> |
| 2310 | <li>When an application is no longer refundable, the server |
| 2311 | sets a longer validity period — typically a number of days. </li> |
| 2312 | <li>For a free application, the server sets the validity period to a very high |
| 2313 | value (<code>long.MAX_VALUE</code>). This ensures that, provided the Policy has |
| 2314 | cached the validity timestamp locally, it will not need to recheck the |
| 2315 | license status of the application in the future.</li> |
| 2316 | </ul> |
| 2317 | |
| 2318 | <p>The ServerManagedPolicy implementation uses the extracted timestamp |
| 2319 | (<code>mValidityTimestamp</code>) as a primary condition for determining whether |
| 2320 | to recheck the license status with the server before allowing the user access to |
| 2321 | the application. </p> |
| 2322 | |
| 2323 | <h4>Retry period and maximum retry count</h4> |
| 2324 | |
| 2325 | <p>In some cases, system or network conditions can prevent an application's |
| 2326 | license check from reaching the licensing server, or prevent the server's |
| 2327 | response from reaching the Android Market client application. For example, the |
| 2328 | user might launch an application when there is no cell network or data |
| 2329 | connection available — such as when on an airplane — or when the |
| 2330 | network connection is unstable or the cell signal is weak. </p> |
| 2331 | |
| 2332 | <p>When network problems prevent or interrupt a license check, the Android |
| 2333 | Market client notifies the application by returning a "RETRY" response code to |
| 2334 | the Policy's <code>processServerResponse()</code> method. In the case of system |
| 2335 | problems, such as when the application is unable to bind with Android Market's |
| 2336 | ILicensingService implementation, the LicenseChecker library itself calls the |
| 2337 | Policy <code>processServerResonse()</code> method with a "RETRY" response code. |
| 2338 | </p> |
| 2339 | |
| 2340 | <p>In general, the RETRY response code is a signal to the application that an |
| 2341 | error has occurred that has prevented a license check from completing. |
| 2342 | |
| 2343 | <p>The Android Market server helps an application to manage licensing under |
| 2344 | error conditions by setting a retry "grace period" and a recommended maximum |
| 2345 | retries count. The server includes these values in all license check responses, |
| 2346 | appending them as extras under the keys "GT" and "GR". </p> |
| 2347 | |
| 2348 | <p>The application Policy can extract the GT and GR extras and use them to |
| 2349 | conditionally allow access to the application, as follows:</p> |
| 2350 | |
| 2351 | <ul> |
| 2352 | <li>For a license check that results in a RETRY response, the Policy should |
| 2353 | cache the RETRY response code and increment a count of RETRY responses.</li> |
| 2354 | <li>The Policy should allow the user to access the application, provided that |
| 2355 | either the retry grace period is still active or the maximum retries count has |
| 2356 | not been reached.</li> |
| 2357 | </ul> |
| 2358 | |
| 2359 | <p>The ServerManagedPolicy uses the server-supplied GT and GR values as |
| 2360 | described above. The example below shows the conditional handling of the retry |
| 2361 | responses in the <code>allow()</code> method. The count of RETRY responses is |
| 2362 | maintained in the <code>processServerResponse()</code> method, not shown. </p> |
| 2363 | |
| 2364 | |
| 2365 | <pre> public boolean allowAccess() { |
| 2366 | long ts = System.currentTimeMillis(); |
| 2367 | if (mLastResponse == LicenseResponse.LICENSED) { |
| 2368 | // Check if the LICENSED response occurred within the validity timeout. |
| 2369 | if (ts <= mValidityTimestamp) { |
| 2370 | // Cached LICENSED response is still valid. |
| 2371 | return true; |
| 2372 | } |
| 2373 | } else if (mLastResponse == LicenseResponse.RETRY && |
| 2374 | ts < mLastResponseTime + MILLIS_PER_MINUTE) { |
| 2375 | // Only allow access if we are within the retry period or we haven't used up our |
| 2376 | // max retries. |
| 2377 | return (ts <= mRetryUntil || mRetryCount <= mMaxRetries); |
| 2378 | } |
| 2379 | return false; |
| 2380 | }</pre> |
| 2381 | |