Giter Club home page Giter Club logo

googleplaylicenseverification's Introduction

Google Play Application License Verification
----------------------------------------------

Author: Erik Hemming / Unity Technologies (twitter: _eriq_)

About the plugin
----------------

This is an example of how Google Play Application Licensing [1] can be integrated into any Unity application, with a minimum of additional Java code (everything except the Service Binder is written in C#). The plugin also loads the Java code loaded at runtime [2] (i.e. the classes.dex in the .apk does no include any LVL code).

The code can also be used in conjunction with an online verification mechanism [3], where the result of the LVL check is sent to a server for proper inspection.

For detailed explanation on Google Play License Verification mechanism, please have at the very informative 'Evading Pirates and Stopping Vampires' [4] presentation from Google I/O 2011.

[1] http://developer.android.com/guide/market/licensing/index.html
[2] http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html
[3] http://code.google.com/p/android-market-license-verification
[4] http://www.google.com/events/io/2011/sessions/evading-pirates-and-stopping-vampires-using-license-verification-library-in-app-billing-and-app-engine.html


How to use
----------

The logic of the plugin is centered around a C# script file, CheckLVLButton.cs, which serves as an example how the LVL check could be integrated in an existing application. This single C# file is responsible for loading the Java code, setting up and calling the LVL backend, and finally deciphering the result.

Please note that the plugin cannot work without the public LVL key, which can be obtained from the publishing account at Google Play. Have a look in CheckLVLButton.cs for the line
	m_PublicKey_Base64 = "<Insert LVL public key here>";
and replace the string with your personal LVL key.


How to (Re-)Compile the Java source
-----------------------------------

First, make sure you have the JDK [1] and ANT [2] installed - while OSX usually comes with these pre-installed, Windows users need to download and install them manually. Then, make sure you have a fairly recent Android SDK [3] - at least API-15.

Before compiling the code the project must be initialized to have the local.properties file updated with path to the (local) Android SDK:

	$ cd <project_root>/Assets/LicenseVerification/JavaSource
	$ cp ../../Plugins/Android/AndroidManifest.xml .
	$ android update project -p .

Now you can use
	$ ant help		to display the help message.
	$ ant clean		to remove output files created by the build target.
	$ ant build		to build the classes.jar (classes.txt) library for use with Unity Android.

[1] http://www.oracle.com/technetwork/java/javase/downloads/index.html
[2] http://ant.apache.org/
[3] http://developer.android.com/sdk/index.html


Detailed instructions how the plugin was created
------------------------------------------------

1) Add the patched manifest

1.1) Create the Android plugins directory.

	$ mkdir <project_root>/Assets/Plugins/Android
	$ cd <project_root>/Assets/Plugins/Android

1.2) Copy the default AndroidManifest.xml used by Unity. This is the normal path used on OSX - the Windows path starts with C:\Program Files\Unity\Data\

	$ cp /Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/AndroidManifest.xml .

1.3) Edit the AndroidManifest.xml, and add permissions related to LVL.

	$ diff -rupN /Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/AndroidManifest.xml AndroidManifest.xml
	--- /Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/AndroidManifest.xml	2012-03-27 22:25:58.000000000 +0200
	+++ AndroidManifest.xml	2012-03-30 18:41:32.000000000 +0200
	@@ -39,4 +39,9 @@
	                   android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
	         </activity>
	     </application>
	+
	+<!-- patched manifest starts here -->
	+    <uses-permission android:name="android.permission.INTERNET" />
	+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	+    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
	 </manifest>


2) Create JavaSource project

2.1) Create ANT project

	$ mkdir <project_root>/Assets/LicenseVerification/JavaSource
	$ cd <project_root>/Assets/LicenseVerification/JavaSource
	$ android create project -t android-15 -p . -k com.unity3d.plugin.lvl -a dummy_activity

2.2) Remove generated files which we don't use.

	$ rm -rf res/
	$ rm src/com/unity3d/plugin/lvl/dummy_activity.java


2.3) Edit build.xml to add support for obfuscated .jar generation

	$ diff -rupN build_dist.xml build.xml
--- build_dist.xml	2012-03-30 18:36:07.000000000 +0200
+++ build.xml	2012-03-31 11:38:00.000000000 +0200
@@ -80,4 +80,60 @@
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />
 
	+    <target name="-code-gen">
	+    </target>
	+
	+    <target name="-create-jar" depends="-compile,-post-compile">
	+        <property name="jar-name" value="lic_check_plain.jar" />
	+        <property name="plugin.jar" value="${out.absolute.dir}/${jar-name}" />
	+
	+        <zip basedir="${out.classes.absolute.dir}"
	+             destfile="${plugin.jar}"
	+             filesonly="true"
	+             excludes="**/*.meta"
	+             />
	+    </target>
	+
	+    <target name="-obfuscate" depends="-create-jar">
	+        <property name="obfuscated-name" value="lic_check_obfuscated.jar" />
	+        <property name="obfuscated.jar" value="${out.absolute.dir}/${obfuscated-name}" />
	+
	+        <property name="proguard.jar" location="${android.tools.dir}/proguard/lib/proguard.jar" />
	+        <taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="${proguard.jar}" />
	+
	+        <pathconvert property="android.libraryjars" refid="android.target.classpath">
	+            <firstmatchmapper>
	+                <regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/>
	+                <identitymapper/>
	+            </firstmatchmapper>
	+        </pathconvert>
	+                
	+        <proguard>
	+            -include      "${proguard.config}"
	+            -injars       ${plugin.jar}
	+            -outjars      "${obfuscated.jar}"
	+            -libraryjars  "${android.libraryjars}"
	+        </proguard>
	+    </target>
	+
	+    <target name="build" depends="-dex">
	+        <property name="zip.file" location="${out.absolute.dir}/classes.zip" />
	+        <property name="out.name" value="classes_jar.txt" />
	+        <property name="out.path" location="../" />
	+        <property name="out.file" location="${out.path}/${out.name}" />
	+        <zip basedir="${out.absolute.dir}"
	+             includes="classes.dex"
	+             destfile="${zip.file}"
	+             filesonly="true"
	+             excludes="**/*.meta"
	+             />
	+        <copy file="${zip.file}" tofile="${out.file}"/>
	+    </target>
	+
	+    <target name="help">
	+        <echo>Android Ant Build. Available targets:</echo>
	+        <echo>   help:      Displays this help.</echo>
	+        <echo>   clean:     Removes output files created by the build target.</echo>
	+        <echo>   build:     Builds the classes.jar (classes.txt) library for use with Unity Android.</echo>
	+    </target>
	 </project>

2.4) Enable ProGuard obfuscation by adding a line to project.properties :

	proguard.config=proguard-project.txt

2.5) Edit the proguard-project.txt file, and add :

	-target 1.6
	-optimizationpasses 2
	-dontusemixedcaseclassnames
	-dontskipnonpubliclibraryclasses
	-dontpreverify
	-keepattributes InnerClasses,EnclosingMethod
	
	-optimizations !code/simplification/arithmetic
	
	-keep class * { public <methods>; !private *; }

3) Add some C# code load the Java classes_jar.txt

	byte[] classes_jar = ServiceBinder.bytes;

	System.IO.File.WriteAllBytes(Application.temporaryCachePath + "/classes.jar", classes_jar);
	System.IO.Directory.CreateDirectory(Application.temporaryCachePath + "/odex");

	m_Activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
	AndroidJavaObject dcl = new AndroidJavaObject("dalvik.system.DexClassLoader",
	                                              Application.temporaryCachePath + "/classes.jar",
	                                              Application.temporaryCachePath + "/odex",
	                                              null,
	                                              m_Activity.Call<AndroidJavaObject>("getClassLoader"));
	m_LVLCheckType = dcl.Call<AndroidJavaObject>("findClass", "com.unity3d.plugin.lvl.ServiceBinder");

googleplaylicenseverification's People

Contributors

erique avatar mlong14 avatar over17 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

googleplaylicenseverification's Issues

Response Code: 0, Package Name: <Failed>

I'm trying to test the example project on my Pixel phone.
I've done the following to the project:

  • changed the package name to one of my live apps
  • replaced the value of m_PublicKey_Base64 to the public key of my live app
  • signed the app using the keystore of my live app

I receive a response code of 0, and the response package name is still "<Failed>".
Are there any steps I've missed in getting this to work?

53825920_592339648260912_2623715578900119552_n

Not working on device when built with Unity 2019.1

Hi. Scratching my head here because the code works fine on device when built with 2018.4 but fails to run on device with the following error when built with 2019.1.

05-10 18:35:20.731 26973 26993 E Unity : java.lang.ClassNotFoundException: Didn't find class "com.unity3d.plugin.lvl.ServiceBinder" on path: DexPathList[[zip file "/data/user/0/com.mycompany.mygame/cache/com.mycompany.mygame/classes.jar"],nativeLibraryDirectories=[/system/lib64]]
05-10 18:35:20.731 26973 26993 E Unity : at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer.c(Unknown Source:0)
05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:88)
05-10 18:35:20.731 26973 26993 E Unity : at android.os.Handler.dispatchMessage(Handler.java:102)
05-10 18:35:20.731 26973 26993 E Unity : at android.os.Looper.loop(Looper.java:193)
05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
05-10 18:35:20.731 26973 26993 E Unity : Suppressed: java.io.IOException: No original dex files found

Any ideas?

Open URL from "LU" extra

Hello!

I got this set up and working - I get the "LU" extra, when the response is NOT_LICENSED, but I don't know all the steps I need to take to actually open the url from inside my app.

This part is not covered in the example app and I have trouble getting this to work.

Cheers, Jan

Unable to instantiate activity ComponentInfo error

Android build has error:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.company.appname/com.unity3d.player.UnityPlayerProxyActivity}

Because the Main Activity is in com.unity3d.player.UnityPlayerProxyActivity instead of com.unity3d.player.UnityPlayerActivity.
Kind of annoying that it came like this.

"LU" extras is empty against NOT_LICENSED

I changed the public key with my application public key but not getting any information about license URL. For testing purposes ,We have added our license test account on Play Console and set the license test response and also signed into Play Store App with same test account on device but not getting detail page URL of the app against "LU" key.
screenshot_20190110-124751

Unclear relationship between numerical response code received and its expected meaning

Hello!
The response code you get here is numerical, while Google on its documentation is dealing with string response codes (probably because native LVL already does the conversion in the background, and doesn't mention the numerical ones anywhere). You would want to know what the codes mean if you want to implement behaviour for all the possible responses. Can you update the readme about this? Or maybe I didn't see it?

The conversion of Response codes should be:

private static final int LICENSED = 0x0;
private static final int NOT_LICENSED = 0x1;
private static final int LICENSED_OLD_KEY = 0x2;
private static final int ERROR_NOT_MARKET_MANAGED = 0x3;
private static final int ERROR_SERVER_FAILURE = 0x4;
private static final int ERROR_OVER_QUOTA = 0x5;
private static final int ERROR_CONTACTING_SERVER = 0x101;
private static final int ERROR_INVALID_PACKAGE_NAME = 0x102;
private static final int ERROR_NON_MATCHING_UID = 0x103;

I found out about this digging in the closes Issues and seeing a response of someone about this:
#3 (comment)

This was pretty annoying as Google themselves is using this project as instruction to developers to implement LVL on Unity.

Thanks!

Not working in Unity 2020.3

Building a project that worked fine in Unity 2019.4 now causes the following error in Unity 2020.3:

2021/08/27 14:32:24.237 5315 5338 Error Unity AndroidJavaException: java.lang.SecurityException: Not allowed to bind to service Intent { act=com.android.vending.licensing.ILicensingService pkg=com.android.vending }
2021/08/27 14:32:24.237 5315 5338 Error Unity java.lang.SecurityException: Not allowed to bind to service Intent { act=com.android.vending.licensing.ILicensingService pkg=com.android.vending }
2021/08/27 14:32:24.237 5315 5338 Error Unity at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1838)
2021/08/27 14:32:24.237 5315 5338 Error Unity at android.app.ContextImpl.bindService(ContextImpl.java:1749)
2021/08/27 14:32:24.237 5315 5338 Error Unity at android.content.ContextWrapper.bindService(ContextWrapper.java:756)
2021/08/27 14:32:24.237 5315 5338 Error Unity at com.unity3d.plugin.lvl.ServiceBinder.create(ServiceBinder.java:32)
2021/08/27 14:32:24.237 5315 5338 Error Unity at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
2021/08/27 14:32:24.237 5315 5338 Error Unity at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
2021/08/27 14:32:24.237 5315 5338 Error Unity at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
2021/08/27 14:32:24.237 5315 5338 Error Unity at android.os.Handler.dispatchMessage(Handler.java:102)
2021/08/27 14:32:24.237 5315 5338 Error Unity at android.os.Looper.loop(Looper.java:223)
2021/08/27 14:32:24.237 5315 5338 Error Unity at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
2021/08/27 14:32:24.237 5315 5338 Error Unity at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <00000000

Apparently I'm not the only one getting this error:

https://forum.unity.com/threads/google-play-pass-licencing-check-no-longer-working.1122247/

Any ideas about why this is happening and how to fix it?

Required 64 bits for Google Play

Hi there,

After creating the APK and upload it to Google Play Console (with IL2CPP and ARM64 selected), the console gives an error about the lack of 64 bits native code version.

So I've tried to follow the documentation to recompile the sources, but I found it obsolete/deprecated. As I'm not a Java / Android developer I am blocked here. Can you build a jar including 64 bits version or update de build documentation using Android Studio?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.