Android

How to protect your app from illegal copy using Samsung Application License Management(Zirconia)
Aug 19, 2011
8

 

This library runs on Samsung Apps only.

1. About Zirconia for ANDROID

1.1.Overview

As a library providing preventive measures against illegal reproduction, Zirconia for ANDROID can be used in Samsung Mobile devices. This library is supplied as a form of Java package that can be used in ANDROID development environments and includes JNI Native Library (*.so).

Zirconia inspects the license of applications being executed to prevent illegal use. Zirconia checks for license from the license server upon the initiation of an application and stores it in device. It also checks for license from the server if the stored license has been removed or damaged. The license from the server is unique for each device and application. Therefore, when an application in a certain device is reproduced into another device, the application will not be executed correctly.

1.2.License Inspection Process

Zirconia’s interior action process for checking a license is as below:

  • Zirconia makes an inquiry to check for a license stored at a device.
  • If a valid license is identified, a restriction for the application use will be removed.
  • When a license does not exist or is not valid, the information of the device and application will be sent to the license server. (Once license is stored in the storage device, internet connection is not required anymore.)
  • If the application has been purchased for use in the device, the license server transmits the license back to Zirconia of the device.
  • Zirconia stores the received license into a storage device.
  • Return to Step 1.

The above procedures are automatically carried out by Zirconia and the user is not involved.

2. Procedures before using Zirconia for ANDROID

Several preliminary procedures are required before using the library of Zirconia for ANDROID Package JAR and JNI Native Library should be added to the project, followed by addition of the manifest permission. For details, please refer to the following section.

2.1.Adding JAR

File configuration of Zirconia for ANDROID includes Zirconia.jar, a JAR file, and libnativeinferface.so, JIN Native Library. First, add Zirconia.jar to the Android application project. The following figure shows an example of Eclipse Project.

Figure1 : Add JAR to application project
2.2.Add JIN Native Library

Create a folder, "libs/armeabi," under the project route path, and copy and place libnativeinterface.so, a JNI Native Library, into the folder. The following figure shows an example of Eclipse Project.

Figure2 : Add JNI Native Library to application project
2.3.Add Permission

To inspect the validity of a license and to make an inquiry of license check to the server, Zirconia for ANDROID needs device information and internet connection. For this purpose, permission for READ_PHONE_STATE and INTERNET should be added to the manifest of the application. See example in figure below.

Figure3 : Adding permission to the manifest of the application project
2.4.Coding instructions
  • Do not repeatedly and excessively call the Zirconia.checkLicense() method. Though Zirconia is not oversized, it uses File I/O, Encoding/Decoding, and Internet Communication to make an inquiry and storage. When Zirconia.checkLicense() method is called repeatedly, a lot of internal threads will be created, and resources will be wasted. For example, if this function is called by a frequently operated action handler, application performance may be influenced due to continual actions of File I/O and Encoding/Decoding.
  • Create a short Zirconia action listener method. Basically, Zirconia does not return license validity inspection results in boolean. Zirconia.checkLicense() works asynchronously, and the method of the listener object is called when the license validity inspection is terminated. Internal thread of Zirconia will survive while the action listener method is working, so the action listener method should be terminated first in order to end this thread.
  • Zirconia may not work well if the device's network is offline or in airplane mode. Therefore, users are advised to activate the device's network before the application initializes Zirconia.

3. Application Procedure of Zirconia for ANDROID

Though Zirconia for ANDROID is composed of several classes, only Zirconia is actually in use. In this class, few methods exist, and their operation methods are relatively simple. Coding procedures for the application of Zirconia are as below:

  • Create an object of Zirconia class.
  • Prepare a class inheriting the LicenseCheckListener interface.
  • Create an object of the class prepared in Step 2, and transfer it to the object created in Step 1 through Zirconia.setLicenseCheckListener() method.
  • License validity inspection and inquiry are carried out by calling Zirconia.checkLicense(). This process may be repeated several times; the method of the listener object created in Step 3 is called when the license verification is completed.

Each step of the above procedures can be implemented at any stage in the application. For example, the above procedure can be implemented at the game initiation stage if you want to prohibit the usage of the entire stage by a user without purchasing the game application. Otherwise, it can also be implemented at the end of the first stage if only the first stage needs to be opened.

See the following sample code:

package com.samsung.zirconia.test;

                import android.app.Activity;
                import android.os.Bundle;
                import android.os.Handler;
                import android.util.Log;
                import android.widget.TextView;

                import com.samsung.zirconia.*;
                
                
                /* Listener class to receive the results of license verification and inquiry */
                class MyLicenseCheckListener implements LicenseCheckListener {

                                /* In case the results of license verification and inquiry are normal */
                                @Override
                                public void licenseCheckedAsValid() {
                                                Log.d("ZirconiaTest", "License is valid");
                                                ownerHandler.post(new Runnable() {
                                                                public void run() {
                                                                                ownerTextView.setText("License is valid");
                                                                }
                                                });
                                }
                                /* In case the results of license verification and inquiry are abnormal */
                                @Override
                                public void licenseCheckedAsInvalid() {
                                                Log.d("ZirconiaTest", "License is invalid");
                                                ownerHandler.post(new Runnable() {
                                                                public void run() {
                                                                                ownerTextView.setText("License is invalid");
                                                                }
                                                });
                                }

                                Handler ownerHandler;
                                TextView ownerTextView;
                }


                public class ZirconiaTest extends Activity {
                                /** Called when the activity is first created. */
                                @Override
                                public void onCreate(Bundle savedInstanceState) {
                                                super.onCreate(savedInstanceState);
                                                Handler handler = new Handler();
                                                TextView tv = new TextView(this);
                                                tv.setText("This is a simple test application for Zirconia!\nPlease hold on while verifying the license...");
                                                setContentView(tv); // setContentView(R.layout.main);
                                                /*
                                                * Create object The first factor is the Application's Activity
                                                * object in progress.
                                                */
                                                Zirconia zirconia = new Zirconia(this);
                                                /*
                                                * Create a listener object , register the listener object to the
                                                * Zirconia object, and inspect the license.
                                                */
                                                MyLicenseCheckListener listener = new MyLicenseCheckListener();
                                                listener.ownerHandler = handler;
                                                listener.ownerTextView = tv;
                                                zirconia.setLicenseCheckListener(listener);
                                                zirconia.checkLicense(false, false);
                                }
                }

4. Appendix – About Zirconia for ANDROID API

4.1.Package com.samsung.zirconia

com.samsung.zirconia is a Java package that provides the function of Zirconia for ANDROID. This package opens one interface and two classes to the external party as below:

 
Interfaces Description
LicenseCheckListener Listener interface to receive the results of license verification and inquiry
 
Classes Description
Zirconia Class that provides main functions of Zirconia
ZirconiaVersion Class that indicates the version of Zirconia
4.2.Interface LicenseCheckListener

This listener interface is called when the license verification and inquiry are completed. The interface can be implemented by a class internally that needs to know the validity of license. After creating an object, the results can be received once the object is transferred to the factor of Zirconia's method Zirconia.setLicenseCheckListerner(). After the verification procedure is completed, Zirconia calls an appropriate method of the object.

Interface LicenseCheckListener
Return Type Description
void licenseCheckedAsInvalid() It is called when the license is not valid.
void licenseCheckedAsValid() It is called when the license is valid.
4.3.Class Zirconia

As the core class of Zirconia for ANDROID, it carries out the license verification and inquiry functions.

 
Field Description
static int EZIRCONIA_KEY_CREATION_FAILED The license cannot be stored in the device. Error in the storage device or the license.
static int EZIRCONIA_LICENSE_MISMATCH Verification and/or inquiry of the license cannot be made due to errors in server or storage device.
static int EZIRCONIA_NOT_PURCHASED The user has not purchased this application.
static int EZIRCONIA_RECEIVE_FAILED License inquiry to server cannot be made due to errors in network or server.
static int EZIRCONIA_SEND_FAILED License inquiry to server cannot be made due to errors in network or server.
static int EZIRCONIA_SERVER_MISMATCH License inquiry to server cannot be made due to errors in server.
static int EZIRCONIA_SUCCESS Success.
 
Constructor
Zirconia(Activity activity) Zirconia object is created and returned.
 
Methods Description
void checkLicense(boolean checkLocalOnly, Boolean dontUseThread)
Calls a suitable method of the listener LicenseCheckListener object after verification and inquiry of the application's license. When this method is called, it inspects the license stored in the storage device. If valid license exists, the licenseCheckedAsValid() method of the listener object is called. If the license does not exist or is not valid, an inquiry of license to server is made. After the inquiry, the license is stored in the device, and the stored license is verified. If the license cannot be attained from the server, the licenseCheckedAsInvalid() of the listener object is called.
If the license stored locally is valid before calling this method or the first factor of this method, checkLocalOnly, is true, no connection to the server is made. The setLicenseCheckListener() method must be called before calling this method to register the listener object.
Factor:
checkLocalOnly – If this factor is true, a license inquiry to the license server is not made even if no valid license exists in the device.
dontUseThread – If this factor is true, the results of license verification and inquiry are directly returned without using internal thread and listener.
boolean deleteLicense()
Deletes the stored application license in the device.
int getError()
Returns recent error codes. Please refer to the summary of constant.
boolean isWorking()
Checks if the checkLicense() method is working.
void setBogusIMEI(String bogusIMEI)
A method used when a development is in progress in the emulator. Sets IMEI temporarily. It does not work in the actual device, so that it must be removed from the code prior to the release.
Factor:
bogusIMEI – temporary IMEI
void setLicenseCheckListener(LicenseCheckListener listener)
Registers a listener that returns the results of license verification and inquiry. It must be called before calling the checkLicense() method.
Factor:
listener - Listener object to receive the results of license verification and inquiry
void setThreadPriority(int newPriority)
Sets the priority of thread that verifies and inquires a license.
Factor:
newPriority – Priority of thread. A point between 1 and 10 can be selected if 5 is the default value.
ZirconiaVersion version()
Returns the library version of Zirconia.
4.4.Class ZirconiaVersion

It is the class that indicates the version of Zirconia. It is used to have a returning value by calling Zirconia.version().

Class ZirconiaVersion
Field Description
int build Build version
int major Major version
int minor Minor version

go to top