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