# DeviceAssure Android Library # The DeviceAssure library utilizes an embedded DeviceAtlas DeviceInfo library and requires certain permissions before it can validate the device. It may be sent directly from the library or via an intermediate server. The validation results may be returned back to the library, to the intermediate server or to a predefined callback URL. The collected data falls into the following groups: * Audio * Build * Build Version * Camera * CPU * Device Dates * Display * GPU * Input Devices * Memory * Permissions * Privilege Escalation * Sensor * Storage * System Properties * Telephony * USB * Vibrator * Web The library must be embedded in a host application to function. The library has minimal impact on the host application and uses a background thread, where possible, to avoid blocking the main UI thread. If the background thread does not complete within 10 seconds it will terminate and send the properties gathered up to that point. Upon completion of processing the result of the validation will be returned to the application (if licence permits). ## Requirements ## - JDK version 7 - DeviceAssure licence - DeviceAssure .aar library (this library is responsible for sending collected data to the DeviceAssure service) ### Permissions ### The DeviceAssure library utilises the DeviceAtlas deviceinfo library and requires certain permissions before it can validate the device. By default it defines the following in it's android.manifest file: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.CAMERA" /> ``` The `android.permission.READ_PHONE_STATE` is optional but is required in order to obtain the IMEI, TAC and Manufacturer Code on devices running Android 28 and lower. For devices running Android 29 and higher the IMEI will not be collected unless the calling application has the `READ_PRIVILEGED_PHONE_STATE` permission or carrier privileges, however TAC and Manufacturer Code will still be collected without requiring permissions. The `android.permission.CAMERA` property is required to obtain camera specifications for devices running Android 5.0 and lower. These permissions are defined in the manifest file of the library but can be **overridden** by the host application. **Note:** The TAC is a non PII property that identifies the make and model of the device and is used to validate the device. Omitting the value is possible but may result in an incomplete validation. The following permissions can also optionally be added to the host application's manifest file: ```xml <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_SMS" /> ``` Adding these permissions will enable collection of first call and SMS dates. ### Android versions ### The library has a minimum SDK requirement of API v18 and targets API 30. ## Usage ## The DeviceAssure library is not a standalone application and must be included in a full application to be used. If using Gradle, the following can be added to the build.gradle file to include it. Or, alternatively, the library .aar files can be imported into Android Studio. ### Gradle Build Configuration ### - Copy the the provided DeviceAssure aar libraries from the `ClientLibs` folder to the libs folder of the Android application being developed. - Add the following code to your build.gradle. ```groovy repositories { jcenter() google() flatDir { dirs 'libs' } } ``` ```groovy dependencies { implementation (name:'deviceassure-lib-2.0.7', ext:'aar') } ``` ### Implementation ### There are two approaches available when validating a device. The first and preferred appoach is for the Android application (the client) to call the DeviceAssure library which in turn collects the device data and makes a validation request to the DeviceAssure service. This approach will automatically use the nearest DeviceAssure service endpoint for optimal response time. The validation results are returned to the library and made available to the application via a callback. The results may (optionally) be returned to a predefined callback URL. This approach is called "client to server" validation The second approach is for the Android application (the client) to call the DeviceAssure library purely to retrieve the collected device data. The DeviceAssure library will not make a request to the DeviceAssure service. It is the responsiblity of the calling application to transmit the data to a suitable server and for that server to make the request to the DeviceAssure service. The validation results are returned directly back to the calling server and not to the client application. This approach is called "server to server" validation. The following sections detail how the above is achieved for both approaches. #### Client (Android Device) to Server validation #### There are three main steps to validate a device in the client to server approach: 1. Initialize the DeviceAssure library with the application context. 2. Call the ```check()``` method with licence key and callback handler. This method will collect the device data and call the DeviceAssure service. 3. Handle the validation results returned via the callback class. The DeviceAssure library should be initialized in a custom application class in the ```onCreate()``` method. The ```check()``` method may be called from anywhere in the application but it is recommended that the call is made either on install or on create of the application. An exception to this is if certain permissions are required to be granted before calling the library, for example to allow collection of the TAC. The Callback handler is called either on a successful result or when an error occurred. This allows the application to react to the result of the check. The examples below make the call during the ```onCreate()``` of the MainActivity and assume that the library is already available for use either via Gradle or via an imported .aar file. ##### Java Implementation Example ##### The suggested implementation is as follows: ```java import android.app.Application; import com.deviceassure.android.library.networking.DeviceValidation; public class SampleApplication extends Application { @Override public void onCreate() { super.onCreate(); // initialize the DeviceAssure library. DeviceValidation.init(this.getApplicationContext()); // this check() method can be called from anywhere. Calling it here will // verify the device every time the application runs. DeviceValidation.check("<YOUR_LICENCE>", new CallbackHandler(this)); } } ``` Definition of a callback handler to handle the results: ```java import org.json.JSONObject; import com.deviceassure.android.library.networking.Callback; public class CallbackHandler implements Callback { private MainActivity activity; public CallbackHandler(MainActivity activity) { this.activity = activity; } @Override public void progressUpdate(Integer percent) { } @Override public void taskComplete(JSONObject result) { // the validation results sent back from the DeviceAssure service. activity.displayResult(result.toString()); } @Override public void handleError(String errorStr) { activity.displayResult(errorStr); } } ``` #### Server to Server validation #### There are five main steps to validate a device in the server to server approach: 1. Initialize the DeviceAssure library with the application context. 2. Call the ```getData()``` with callback handler. This method will collect the device data and return it via a callback to the application. 3. The collected data should be transmitted in a secure manner to a suitable server. 4. The server makes a request to the DeviceAssure service with the collected data and HTTP headers. 5. The validation results are returned directly to the server and not to the client. Please see the Implementation Guide for further details on how the data should be transmitted to the DeviceAssure service. Note that the licence key is not required on the client. It must however be passed when making the call to the DeviceAssure service on the server side. The DeviceAssure library should be initialized in a custom application class in the ```onCreate()``` method. The ```getData()``` method may be called from anywhere in the application but it is recommended that the call is made either on install or on create of the application. An exception to this is if certain permissions are required to be granted before calling the library, for example to allow collection of the TAC. The Callback handler is called either on a successful collection of data or when an error occurred. The examples below make the call during the ```onCreate()``` of the MainActivity and assume that the library is already available for use either via Gradle or via an imported .aar file. ##### Java Implementation Example ##### The suggested implementation is as follows: ```java import android.app.Application; import com.deviceassure.android.library.networking.DeviceValidation; public class SampleApplication extends Application { @Override public void onCreate() { super.onCreate(); // initialize the DeviceAssure library. DeviceValidation.init(this.getApplicationContext()); // Retrieve the collected data and handle in a suitable callback class. // Calling it here will collect data every time the application runs. DeviceValidation.getData(new CallbackHandler(this)); } } ``` Definition of a callback handler to handle the collected data. ```java import org.json.JSONObject; import com.deviceassure.android.library.networking.Callback; public class CallbackHandler implements Callback { private MainActivity activity; public CallbackHandler(MainActivity activity) { this.activity = activity; } @Override public void progressUpdate(Integer percent) { } @Override public void taskComplete(JSONObject collectedData) { // The data collected from the device is passed here. It should be sent // sent securely to a suitable server that will in turn make a request // to the DeviceAssure service. activity.displayResult(collectedData.toString()); } @Override public void handleError(String errorStr) { activity.displayResult(errorStr); } } ``` ### DeviceAssure sourcecode ### The source code for both the DeviceAssure and the DeviceInfo libraries is available upon request. ## Copyright ## Copyright (c) DeviceAtlas Limited 2022. All rights reserved. https://deviceatlas.com