No, we could just store some key in the preferences to make sure that the
preference file hasn't been blindly deleted. It's not perfect, it's just
meant to be a deterrent. (If we're providing an initial grace period, we've
already established that the application isn't highly concerned about the
security of the license check -- and a deterrent is still better than the
alternative.)

-- 
Trevor Johns
Google Developer Programs, Android
http://developer.android.com


On Wed, Jul 28, 2010 at 4:00 PM, Mark Carter <[email protected]> wrote:

> How does that trip wire work? If the user clears the app data, then surely
> the only way you could tell is by storing something outside of the app's
> scope (like on the server or in the Market app).
>
> I'd be happy to contribute LenientPolicy. Actually modified it today so
> that it caches LICENSED and NOT_LICENSED responses (in the same way as
> ServerManagedPolicy) so that it doesn't have to call the server every time.
> This means LenientPolicy now uses the Obfuscator and no longer stores any
> non-obfuscated prefs. I'm happy to do the Javadoc but don't really have time
> to do the JUnit tests. Anyway, shouldn't someone other than the implementer
> do those? ;)
>
> On 29 July 2010 00:43, Trevor Johns <[email protected]> wrote:
>
>> I was considering writing something like this into the library, but it
>> wasn't a priority since I figured somebody would be able to defeat it easily
>> (as you mentioned ;)). If you be willing to clean it up (add JavaDocs and
>> JUnit tests) and sign a CLA, I'd be happy to accept it as a contribution for
>> a future release. Assuming you were amenable to the idea, of course.
>>
>> That being said, I'm currently working on a patch to ServerManagedPolicy
>> that will allow specifying an initial grace period in case the user is
>> offline during the initial license check. It will also have a tripwire that
>> can optionally delete an application's data if it detects the licensing
>> shared preferences have been deleted -- a consequence for trying to take
>> advantage of the grace period as a workaround. Since that's at the top of my
>> list, there's a very good chance that will be in r2 of the library.
>>
>> --
>> Trevor Johns
>> Google Developer Programs, Android
>> http://developer.android.com
>>
>>  On Wed, Jul 28, 2010 at 8:41 AM, Mark Carter <[email protected]>wrote:
>>
>>>  I've been playing around with the new LVL announced yesterday and
>>> wanted to write a policy which only stops the user when it is certain
>>> that he does not have a license.
>>>
>>> In other words, the policy will only "dontAllow" the user if the last
>>> meaningful response from the licensing service was NOT_LICENSED.
>>> Therefore, if the user is offline when they first use the app, then
>>> they will be allowed in.
>>>
>>> The idea behind this is that I don't want genuine paying users to ever
>>> (within reason) be inconvenienced by this licensing system.
>>>
>>> The downside is that all the user needs to do is clear the app data
>>> and go offline before restarting the app. The app will continue
>>> working until they go online (and restart the app).
>>>
>>> My thoughts are:
>>>
>>> 1. Most users won't know about that workaround
>>> 2. Those users that are happy to use that workaround, probably
>>> wouldn't pay for the app anyway
>>>
>>> Any other thoughts?
>>>
>>> ===
>>>
>>> Here is the code:
>>>
>>> public void processServerResponse(LicenseResponse response,
>>> ResponseData rawData) {
>>>        mLastResponse = response;
>>>        if (response == LicenseResponse.LICENSED || response ==
>>> LicenseResponse.NOT_LICENSED) {
>>>                // note - we don't want to say "IS_LICENSED" because that
>>> can be
>>> hacked
>>>                SharedPreferences prefs =
>>> PreferenceManager.getDefaultSharedPreferences(this.mContext);
>>>                Editor edit = prefs.edit();
>>>                if (response == LicenseResponse.LICENSED) {
>>>                        edit.remove(NOT_LICENSED_PREF);
>>>                } else if (response == LicenseResponse.NOT_LICENSED) {
>>>                        edit.putBoolean(NOT_LICENSED_PREF, true);
>>>                }
>>>                edit.commit();
>>>        }
>>> }
>>>
>>> public boolean allowAccess() {
>>>        if (mLastResponse == null) {
>>>                // this is the first call
>>>                return false;
>>>        }
>>>        switch (mLastResponse) {
>>>        case LICENSED:
>>>                return true;
>>>        case NOT_LICENSED:
>>>                return false;
>>>        default:
>>>                return !isDefinitelyNotLicensed();
>>>        }
>>> }
>>>
>>> public boolean isDefinitelyNotLicensed() {
>>>        // if we don't know, then its NOT definitely not licensed.
>>>        SharedPreferences prefs =
>>> PreferenceManager.getDefaultSharedPreferences(mContext);
>>>        return prefs.getBoolean(NOT_LICENSED_PREF, false);
>>> }
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Android Developers" group.
>>> To post to this group, send email to [email protected]
>>> To unsubscribe from this group, send email to
>>> [email protected]<android-developers%[email protected]>
>>> For more options, visit this group at
>>> http://groups.google.com/group/android-developers?hl=en
>>>
>>
>>
>>
>>
>>
>>
>


-- 
Trevor Johns

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to