Download as pdf or txt
Download as pdf or txt
You are on page 1of 28

Development

Best Practices
APOS A8

1.1
Public

Latin America Region


09/11/2020

www.ingenico.com
28/32, boulevard de Grenelle, 75015 Paris - France / (T) +33 (0)1 58 01 80 00 / (F) +33 (0)1 58 01 91 35

Ingenico Group – S.A. au capital de 61 493 241 € / 317 218 758 RCS PARIS
1.1 Development Best Practices Public

Contents

1 Introduction........................................................................................ 4
1_1 Purpose and Scope............................................................................................. 4

2 APOS A8 ............................................................................................. 5
2_1 USDK .................................................................................................................. 5
2_2 BC ....................................................................................................................... 5

3 Customizing terminal ........................................................................ 6


3_1 Block status bar pulldown ................................................................................... 6
Code snippet ................................................................................................................................ 6

3_2 Disabling physical buttons................................................................................... 6


Disabling Home Button ................................................................................................................. 6
Code snippet ................................................................................................................................ 7

3_3 Drag-and-drop application uninstall .................................................................... 7


3_4 Low space notification uninstallation ................................................................... 8
3_5 Preventing clearing data ..................................................................................... 8
3_6 Ordering PIN entry keys ...................................................................................... 9
Code snippet ................................................................................................................................ 9
Terminal requirements.................................................................................................................. 9
Checking terminal requirements in runtime .................................................................................. 9

4 Changing default settings password ............................................. 11


4_1 Create an application ........................................................................................ 11
Package name............................................................................................................................ 11
SHA256 value............................................................................................................................. 11
API key ....................................................................................................................................... 11

4_2 Creating an authentication service .................................................................... 12


Defining the service .................................................................................................................... 12
AIDL files .................................................................................................................................... 12
4_2_2_1 Defining an AIDL interface ..................................................................................................... 12
4_2_2_2 Create the IAuthorityCallback.aidl file .................................................................................... 13
4_2_2_3 Create the IAuthorityRequest.aidl file ..................................................................................... 13
4_2_2_4 Implement the interface .......................................................................................................... 13
4_2_2_5 Expose the interface ............................................................................................................... 14

Ingenico document - Reproduction or disclosure prohibited without written authorization


2/28 Please check document validity before using
1.1 Development Best Practices Public

4_3 Screens to authenticate .................................................................................... 15


Example ...................................................................................................................................... 16

4_4 Handling authentication..................................................................................... 16


Authentication service via UI ...................................................................................................... 16
4_4_1_1 UI process example ................................................................................................................ 17
Authentication service without user interaction .......................................................................... 17
4_4_2_1 Silent process example .......................................................................................................... 17

4_5 Protecting the custom authentication application .............................................. 18

5 Virtual PIN skin ................................................................................ 19


5_1 Using a skin application .................................................................................... 19
Setting list ................................................................................................................................... 19

5_2 Skin application structure .................................................................................. 20


5_3 Keyboard layout file .......................................................................................... 21
Extra text view ............................................................................................................................ 21
Hints ........................................................................................................................................... 21

5_4 Built-in settings.................................................................................................. 22


Content example ........................................................................................................................ 23

5_5 Package name of the skin module .................................................................... 23

6 Visual impaired settings.................................................................. 24


6_1 Using USDK ...................................................................................................... 25
Extra settings method ................................................................................................................. 25
Start PIN entry method ............................................................................................................... 26

6_2 Using BC APOS ................................................................................................ 26


6_3 Audio feedback ................................................................................................. 26

7 Development hints........................................................................... 27
7_1 Inserting test encryption keys............................................................................ 27
Mapping KAP ID to BC ............................................................................................................... 27

Ingenico document - Reproduction or disclosure prohibited without written authorization


3/28 Please check document validity before using
1.1 Development Best Practices Public

1 Introduction

1_1 Purpose and Scope


This document is the Development Best Practices for APOS A8. It has been developed to aid
companies to write a reliable software and prevent common problems found when users interact with
applications running on APOS A8.

This guide will help to understand what it should be considered in the application development to
prevent misusage of the equipment. Thus, all the tips found here will require someone to write code. It
is not the scope of this document teaching:
 Android development
 How to write a payment application
 Either BC or EMV concepts
 How to use the A8 Settings screen

Read this guide to understand and make best use of your terminal in order to create a reliable and
stable application.

This document is updated according to:


 BC version: 4.16
 USDK API version: 2.3.12

Ingenico document - Reproduction or disclosure prohibited without written authorization


4/28 Please check document validity before using
1.1 Development Best Practices Public

2 APOS A8
Creating applications to run on an APOS A8 device will eventually use non-Android hardware
modules, and to access those modules it will require either the USDK library or the BC APOS library.

2_1 USDK
The USDK is a service which supports many APIs for using the terminal device functions. If any
application wants to use the terminal device functions, it needs to register on service.
To detailed guide on what is in the interface and how to use, please access the link
https://arke.landicorp.com/en/sdk-introduction.

2_2 BC
BC is an acronym to Biblioteca Compartilhada (“Shared Library” in English) and is a specification
currently maintained by Associção Brasileira das Empresas de Cartão e Serviços (as known as
ABECS) consortium. ABECS is compound by the main credit card issuers, card brands, acquirers and
processors in Brazil.
BC specification aims to simplify and normalize card transaction process. Ingenico delivers an Android
library that implements the BC specification version 1.08a. This library is intended to use on APOS
terminals, and it includes the USDK library internally.

BC APOS

USDK

Ingenico document - Reproduction or disclosure prohibited without written authorization


5/28 Please check document validity before using
1.1 Development Best Practices Public

3 Customizing terminal
This section will show how to customize an APOS to provide a better experience to users.

3_1 Block status bar pulldown


Pulling down the notification bar gives access to several settings (see figure below).

In order to prevent this, the application must enable or disable programmatically using UStatusBar.
NOTE: This is feature requires BC 4.15 or USDK version 2.3.5_20190805.

Code snippet

UStatusBar statusBar = DeviceHelper.me().getStatusBar();


try {
// enables/disables status bar pulldown
statusBar.setPanelExpandEnabled(enable);

// checks status bar status


BooleanValue isEnabled = new BooleanValue();
statusBar.isPanelExpandEnabled(isEnabled);
} catch (RemoteException e) {}

3_2 Disabling physical buttons


In order to prevent a misuse of physical buttons, it’s possible to disable some of the buttons.

Disabling Home Button


On regular Android devices the home button can’t be disabled. However, apps running on APOS A8
can do that by using the method setHomeKeyEnabled from UKeyboard interface.

Ingenico document - Reproduction or disclosure prohibited without written authorization


6/28 Please check document validity before using
1.1 Development Best Practices Public

Application has to add titan.extperm.UX_SET and titan.extperm.UX_GET permissions on


manifest file. If the application has no corresponding permission, the API will throw a security
exception.
Note: This is feature requires BC 4.15 or USDK version 2.3.5_20190805.

Code snippet

UKeyboard keyboard = DeviceHelper.me().getKeyboard();


try {
// enables/disables home button
keyboard.setHomeKeyEnabled(enable);
// checks home button status
BooleanValue isEnabled = new BooleanValue();
keyboard.isHomeKeyEnabled(isEnabled);
} catch (RemoteException e) {}

3_3 Drag-and-drop application uninstall


Applications can be uninstalled by long pressing then drag and drop to [Uninstall] menu.

This feature is provided by Android default launcher. In order to disable this there is two ways:
 Customer develops custom launcher to replace the default. This is a too heavy job.
 If default launcher is used, customer can disable [uninstall] function on specific app. See the flow
below:

The package name is the name in AndroidManifest file.

Ingenico document - Reproduction or disclosure prohibited without written authorization


7/28 Please check document validity before using
1.1 Development Best Practices Public

3_4 Low space notification uninstallation


When the memory space reaches a low level, Android launches a low space notification. It is another
way Android allows to uninstall apps.

A strategy is to apply protection to second level of settings, in this case, the Apps settings.

3_5 Preventing clearing data


On application information screen there is a button that clears application data by clicking it. There are
two strategies to protect this button.
The first one is to protect by adding a password to access the application information screen. This
strategy will be covered in another topic.
The second option, covered here, is to write an application to replace the button action. The steps are:
1. Create an activity to customize the behavior of "Clear data" button. This activity will be
responsible handle the button behavior. For example, this activity does nothing but toast a
message.
public class CleanerActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cleaner);
Toast.makeText(this, "Cannot delete data!", Toast.LENGTH_LONG).show();
finish();
}
}

2. Opens AndroidMainfest.xml, add the android:manageSpaceActivity attribute in


application element.
<application
android:name="com.ingenico.lar.BCAppApplication"
android:allowBackup="true"
android:icon="@mipmap/ingenico_icon"
android:label="@string/app_name"
android:manageSpaceActivity="com.ingenico.lar.settings.CleanerActivity"
android:supportsRtl="true"
android:theme="@style/AppTheme">

After installing the app in the device, the Clear data button will change to Manage space. By clicking
it, it will invoke the activity referenced in the android:manageSpaceActivity attribute. In this
example, it will prompt the message Cannot delete data!

Ingenico document - Reproduction or disclosure prohibited without written authorization


8/28 Please check document validity before using
1.1 Development Best Practices Public

3_6 Ordering PIN entry keys


By default, on PIN entry, APOS A8 presents a virtual PIN keyboard with keys in random sequence to
comply with PCI security standard. However, APOS A8 allows to display to the cardholder a sorted
keyboard. In order to accomplish that, the application should send a broadcast message to disable the
disorder parameter.
Since broadcasting is not always effective, it is recommended to delay a certain time after
broadcasting (for example: 100ms) and then call the PIN input interface. Delay is one of the methods
that can improve the success rate of sending broadcast and making it effective. Other methods, as
long as it is sure that broadcast has been sent before PIN input interface is called (e.g. call
sendBroadcast() interface in Application's onCreate()method), can be applied as well.
Once the setup broadcast is sent, the effect will continue until a new broadcast is sent or the POS is
rebooted.

Code snippet

public static final String PINPAD_PINENTRY_SET_SKIN =


"com.landicorp.pinpad.pinentry.server.SET_SKIN";

Intent configureSkin = new Intent(PINPAD_PINENTRY_SET_SKIN);
configureSkin.putExtra("disorder", false);
getActivity().sendBroadcast(configureSkin);

Terminal requirements
The ‘disorder’ property is not available in all terminals. Only terminals with hardware number ending
with “3” allow sort the PIN input keys.

According to PCI and UnionPay security specifications, the virtual PIN entry numbers shall be random
to promote the security. So, setting the ‘disorder’ property to false is not recommended.

Checking terminal requirements in runtime

Ingenico document - Reproduction or disclosure prohibited without written authorization


9/28 Please check document validity before using
1.1 Development Best Practices Public

When there is no guarantee every terminal has a proper hardware ending number, it is recommended
the application checks it. See below the snippet of a code to check whether the terminal allows sorting
the virtual PIN keys.

private boolean hardwareSupportsVisualImpairedSettings() {


boolean supports = false;
DeviceInfo deviceInfo = null;
try {
deviceInfo = DeviceHelper.me().getDeviceManager().getDeviceInfo();
supports = deviceInfo.getHardwareVersion().endsWith("3");
} catch (RemoteException e) {
Log.d(TAG, "hardwareSupportsVisualImpairedSettings: ", e);
}
return supports;
}

Ingenico document - Reproduction or disclosure prohibited without written authorization


10/28 Please check document validity before using
1.1 Development Best Practices Public

4 Changing default settings password


This topic details how to replace or even remove the default settings password 260089.

4_1 Create an application


There is no way to change or remove the device’s default password. Instead, an application to handle
the authentication must be created to override the standard authentication service. The Android
manifest file must contain an API key created by Ingenico. The developer must require this API key via
Jira ticket providing the package name and the SHA256 value.

Package name
This is the value in the Android manifest file inserted when the project was created. For example:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ingenico.lar.bcapp">

SHA256 value
Every Android application must be generated with a signature key store. This key store may be
created using a tool that has this purpose. The next example considers that the Android project uses a
key store file, called myapp.keystore, and shows how to get the value SHA256 to add in the Jira ticket
and get the API key.
C:\Users\jwick>keytool -list -v -keystore myapp.keystore
Enter keystore password:
Keystore type: jks
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: myapp


Creation date: 27/08/2020
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=John Wick, OU=Parabellum, O=Parabellum, L=New York, ST=NY, C=US
Issuer: CN=John Wick, OU=Parabellum, O=Parabellum, L=New York, ST=NY, C=US
Serial number: f725902
Valid from: Thu Aug 27 17:46:29 BRT 2020 until: Wed Nov 25 17:46:29 BRT 2020
Certificate fingerprints:
MD5: DD:4D:AF:7A:72:06:49:30:43:8D:70:7E:F5:72:75:D8
SHA1: AC:16:0C:BD:DE:D7:67:CD:FE:0A:5A:F1:33:85:EE:BD:04:72:6F:12
SHA256:
16:05:A3:DA:C7:BE:D9:A4:67:04:0E:EA:59:74:D4:16:E0:B9:BC:D8:CB:67:76:A1:C8:58:85:1E:39:E3:68:A
C
Signature algorithm name: SHA256withDSA
Subject Public Key Algorithm: 2048-bit DSA key
Version: 3

API key

Ingenico document - Reproduction or disclosure prohibited without written authorization


11/28 Please check document validity before using
1.1 Development Best Practices Public

Based on the package name and the SHA256 value, Ingenico will generate the corresponding API-key
value to add in the Android manifest file, inside the application element, as seen in the following
example.
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<meta-data
android:name="com.android.settings.API_KEY"

android:value="4332706C38432B756671767844336A54694A4E7356696957493437744E4A7870394
F76636B50414661486F6E6D74704F646F5338623256746E524D516F39744C324470647547632B32436
2490A6566396175574479632B7265666B664F75307475653846783434413659746B476E48713554556
C34746E7238334A695A7A6B557266545068652F384D4C6E432B626352544E6F5668327164580A51475
97157385649496E6C484A437673557464635A4D376E49535672735979336A394773564D575331464F6
E6E62513549346943453641792F3242704B783750676D4B642F514C4338656F330A5971677346366A6
F4D6F753159666D5757717948314D6444373432554149355A555659767467565852454953704930664
74E7A7A576D3643557A4B45693764657A55776B6E656955533552330A5746417838336262597773684
74B35593875526D695975777A63716A4F5771536A7673776D673D3D0A" />

</application>

4_2 Creating an authentication service


Next we will see the steps to create a service to override the default authentication service.

Defining the service


The application must have a service to handle the authentication that will handle the
“com.android.settings.CUST_AUTHORITY” action. Suppose the class service is called
MiServicioAutenticacion, so in the Android manifest it will be set like this:
<service
android:name="com.android.settings.authority.MiServicioAutenticacion"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.android.settings.CUST_AUTHORITY" />
</intent-filter>
</service>

AIDL files
The Android Interface Definition Language (AIDL) allows to define the programming interface that both
the client and service agree upon in order to communicate with each other using interprocess
communication (IPC).

4_2_2_1 Defining an AIDL interface

Ingenico document - Reproduction or disclosure prohibited without written authorization


12/28 Please check document validity before using
1.1 Development Best Practices Public

According to Android documentation, you must define your AIDL interface in an .aidl file, then save it
in the source code (in the src/ directory) of both the application hosting the service and any other
application that binds to the service.
When you build each application that contains the .aidl file, the Android SDK tools generate an IBinder
interface based on the .aidl file and save it in the project's gen/ directory. The service must implement
the IBinder interface as appropriate. The client applications can then bind to the service and call
methods from the IBinder to perform IPC.
To create a bounded service using AIDL, follow these steps:
1. Create the .aidl file: this file defines the programming interface with method signatures.
2. Implement the interface: the Android SDK tools generate an interface in the Java
programming language, based on your .aidl file. This interface has an inner abstract class
named Stub that extends Binder and implements methods from your AIDL interface. You must
extend the Stub class and implement the methods.
3. Expose the interface to clients: implement a Service and override onBind() to return your
implementation of the Stub class.

NOTE: for further information of how AIDL file works consult the Android
documentation at https://developer.android.com/guide/components/aidl.

The application must implement the two AIDLs: IAuthorityCallback.aidl and IAuthorityRequest.aidl. In
both files the package name must be “com.android.settings.authority”.

4_2_2_2 Create the IAuthorityCallback.aidl file


The content of this file is:
// IAuthorityCallback.aidl
package com.android.settings.authority;
interface IAuthorityCallback {
void onAuthorityCallBack(boolean authority, String errorMsg);
}
This is a callback interface to respond to the authorization service.

4_2_2_3 Create the IAuthorityRequest.aidl file


The content of this file is:
// IAuthorityRequest.aidl
package com.android.settings.authority;
import com.android.settings.authority.IAuthorityCallback;

interface IAuthorityRequest {
List<String> requestAuthScreen();
Intent requestAuthority();
void setAuthorityCallback(IAuthorityCallback callback);
}
This is the interface the service should implement.

4_2_2_4 Implement the interface


When you build your application, the Android SDK tools generate a .java interface file named after
your .aidl file. The generated interface includes a subclass named Stub that is an abstract
implementation of its parent interface (in our case it will generate IAuthorityRequest.Stub) and
declares all the methods from the .aidl file.

Ingenico document - Reproduction or disclosure prohibited without written authorization


13/28 Please check document validity before using
1.1 Development Best Practices Public

To implement the interface generated from the .aidl, extend the generated Binder interface and
implement the methods inherited from the .aidl file. Here is an example implementation of the interface
called IAuthorityRequest (defined by the IAuthorityRequest.aidl) using an anonymous
instance:
private IAuthorityRequest mBinder = new IAuthorityRequest.Stub() {

@Override
public List<String> requestAuthScreen() throws RemoteException {
List<String> lists = new ArrayList<>();
lists.add("Main");

return lists;
// return null; // if you wants to not require any password
}

@Override
public Intent requestAuthority() throws RemoteException {
String packageName =
getApplicationContext().getPackageManager().getNameForUid(Binder.getCallingUid());

Intent intent = new


Intent("com.android.settings.ACTION.CUST_AUTHORITY");
return intent;
}

@Override
public void setAuthorityCallback(IAuthorityCallback callback) throws
RemoteException {
mAuthorityCallback = callback;
if (callback == null) {
mHandler.removeMessages(1);
}
}
};

Now the binder is an instance of the Stub class (a Binder), which defines the RPC interface for the
service.

4_2_2_5 Expose the interface


Once you've implemented the interface for your service, you need to expose it to the authorizarion
service so it can bind to it. To expose the interface for your service, extend Service and implement
onBind() to return an instance of your class that implements the generated Stub. Here's an example
service that exposes the IAuthorityRequest interface to the authorization service.
public class MyAuthenticationService extends Service {

private IAuthorityRequest mBinder = new IAuthorityRequest.Stub() {

@Override
public List<String> requestAuthScreen() throws RemoteException {

}

@Override
public Intent requestAuthority() throws RemoteException {

Ingenico document - Reproduction or disclosure prohibited without written authorization


14/28 Please check document validity before using
1.1 Development Best Practices Public


}

@Override
public void setAuthorityCallback(IAuthorityCallback callback) throws
RemoteException {

}
};

@Override
public IBinder onBind(Intent intent) {
return mBinder.asBinder();
}

@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}

Now you have a basic service structure to handle the authorization process.

4_3 Screens to authenticate


The application needs to define what screens under Settings application should request authorization.
Once defined, the method requestAuthScreen() must reflect it. This method returns a list of
Strings representing every screen that will require authorization. The next table shows what settings
page can set the authorization and the respective key word.

/ Settings to request authorization


Settings page Key word

Main Main

WLAN Wifi

Bluetooth Bluetooth

Ethernet Ethernet

Data usage DataUsage

More page Wireless

Buttons Button

Flash Mode FlashMode

Display Display

Sound & notification Notification

Ingenico document - Reproduction or disclosure prohibited without written authorization


15/28 Please check document validity before using
1.1 Development Best Practices Public

Storage Memory

Battery PowerUsage

Apps ManageApplications

Profiles

Location Location

Security Security

Language & input InputMethodAndLanguage

Date & time DateTime

Accessibility Accessibility

Printing Print

About terminal DeviceInfo

If the method requestAuthScreen returns null, then no password will be required.

Example
Suppose the customer wants to request a password for WLAN and Apps settings only. The following
code snippet shows how to set this.
@Override
public List<String> requestAuthScreen() throws RemoteException {
List<String> lists = new ArrayList<>();
lists.add("Wifi");
lists.add("ManageApplications");

return lists;
}

4_4 Handling authentication


The application can handle the authorization process using a UI screen or without it, processing a
remote authorization. After informed the current screen needs authorization via
requestAuthScreen() method, the authority service will invoke the requestAuthority()
method.

Authentication service via UI


If the application has an UI, for example to enter a user password, the method
requestAuthority() must return an Intent object corresponding to the activity that will handle
this. The activity has to be defined in the manifest file with an action and the category
“android.intent.category.DEFAULT”.
After authentication, the UI must call the method setResult() followed by the method finish().
The intent object passed in the setResult() must contain the extra parameters:
 “auth_result”: a Boolean type variable that indicates whether it was success or not
 “auth_result_error_msg”: a string with an error text message

Ingenico document - Reproduction or disclosure prohibited without written authorization


16/28 Please check document validity before using
1.1 Development Best Practices Public

4_4_1_1 UI process example


Consider the application has the MainActivity.java that will do the authorization process handles
the action “com.android.settings.ACTION.CUST_AUTHORITY”.
In the manifest file we will find:
<activity android:name=".MainActivity">
<intent-filter android:priority="111">
<action android:name="com.android.settings.ACTION.CUST_AUTHORITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

The requestAuthority() method will return an intent object with the action that will invoke our
activity.
@Override
public Intent requestAuthority() throws RemoteException {
Intent intent = new Intent("com.android.settings.ACTION.CUST_AUTHORITY");
return intent;
}

The authority service will invoke our MainActivity.java. When it verifies the password, it will finish
setting a proper result of the authorization.
public class MainActivity extends AppCompatActivity {

private void setResult(boolean result, String errorMsg) {
Log.d(TAG, "setResult: result=" + result+ ";errorMsg=" + errorMsg);
Intent intent = new Intent();
intent.putExtra("auth_result", result);
intent.putExtra("auth_result_error_msg", errorMsg);
setResult(1000, intent);
finish();
}

}

Authentication service without user interaction


The application can authorize without a user interaction, because it will be handled in a remote
service. In this silent process, the application must return a null object in the requestAuthority()
method and then, it will invoke method onAuthorityCallBack() from the IAuthorityCallback
interface. The service will receive the callback instance via method setAuthorityCallback().

4_4_2_1 Silent process example


Consider the application will request a remote authorization.
The requestAuthority() method will return a null object with the action that will invoke our
activity.
@Override
public Intent requestAuthority() throws RemoteException {
// do remote auth request
return null;
}

Ingenico document - Reproduction or disclosure prohibited without written authorization


17/28 Please check document validity before using
1.1 Development Best Practices Public

The setAuthorityCallback() method will save the callback object that the device authority will
send:
@Override
public void setAuthorityCallback(IAuthorityCallback callback) throws
RemoteException {
mAuthorityCallback = callback;
}
Then, somewhere in the application structure, it will invoke the onAuthorityCallBack() method to
send the auth result.
try {
mAuthorityCallback.onAuthorityCallBack(false, "my error message...");
} catch (RemoteException e) {
}

4_5 Protecting the custom authentication application


As explained before, this process will create an application to override the default authentication and
will not replace the default password. This means that if this application is uninstalled, standard
authentication will handle the process again and the default password 260089 will be used. Therefore,
this application must be protected from either accidental or malicious removal.
The process to protect this app is the same explained in topic 3_3 .

Ingenico document - Reproduction or disclosure prohibited without written authorization


18/28 Please check document validity before using
1.1 Development Best Practices Public

5 Virtual PIN skin


This topic covers how to customize the default virtual PINPAD appearance, the PINPAD keyboard
prompted on screen on PIN input. It is done by creating an isolated virtual PINPAD skin application. It
cannot run by itself and should be treated as a virtual PIN PAD plugin.

5_1 Using a skin application


To enable a virtual PIN PAD skin, the skin application should be installed in the device first. After the
skin application is installed, the device must be rebooted to load the new skin.
It the new skin was created as a default skin, then that skin should already be available, and no extra
action is needed. However, if this is not a default skin, the application should broadcast an action to
enable this. For example, consider a non-default skin application identified by DEMO, so to change to
this skin, that skin, the application must execute these commands:
public static final String SET_SKIN_ACTION =
"com.landicorp.pinpad.pinentry.server.SET_SKIN";
public static final String SKIN_NAME = "skin_name";

Intent intent = new Intent(PinSkin.SET_SKIN_ACTION);
intent.putExtra(SKIN_NAME, "DEMO");
context.sendBroadcast(intent);

Setting list
There are some extras settings the application may change to adjust the skin according to merchant
needs.

/ List of settings
Setting Type Description
String The skin that will be prompt. If this setting isn’t sent, the device
skin_name
default skin will be set.
gravity Integer The location of the virtual PIN PAD. If this setting isn’t sent, the
skin default will take effect.
skb_x Integer The X-pixel coordinate of the virtual PIN PAD. If this setting isn’t
sent, the skin default will take effect.
skb_y Integer The Y-pixel coordinate of the virtual PIN PAD. If this setting isn’t
sent, the skin default will take effect.
skb_width Integer The width of the virtual PIN PAD, ranging from -1 to MAX. The
value -1 means “match_parent”. If this setting isn’t sent, the
skin default will take effect.
skb_height Integer The height of the virtual PIN PAD, ranging from -1 to MAX. The
value -1 means “match_parent”. If this setting isn’t sent, the
skin default will take effect.
show_input Boolean Whether to show the text view or not. If it is true, then the text
view of the skin will be shown (as View.VISIBLE), otherwise it
will be hidden (as View.GONE). The text view is a view in the
skin layout, which shows the user PIN as character “*”.

Ingenico document - Reproduction or disclosure prohibited without written authorization


19/28 Please check document validity before using
1.1 Development Best Practices Public

custom_text String[] This extra can set the text of TextView on the skin layout. The
value is a list of String pairs, where the first String is the id of the
TextView, and the second is the text to show.
handle_back_key Boolean Whether to handle back key of the device. If true, then pressing
the back key on the device will be able to exit virtual PIN PAD,
otherwise you can only exit the virtual PIN PAD by press the
cancel button on virtual PIN PAD.
dim_amount Integer The alpha of virtual PIN PAD dim. The range goes from 0, that is
[0, 100] transparent setting, to 100 will be all black. The virtual PIN PAD
is a Dialog that when it is prompted, the screen will dim.
User cannot click outside the virtual PIN PAD Dialog. So, it’s
suggested not to set a too low dim value, because it may
confuse the user, by making him think clicking outside is allowed.

Example of settings:
intent = new Intent("com.landicorp.pinpad.pinentry.server.SET_SKIN");
intent.putExtra("skin_name", "DEMO");
intent.putExtra("gravity", Gravity.BOTTOM);
intent.putExtra("skb_x", 0);
intent.putExtra("skb_y", 0);
intent.putExtra("skb_width", 580);
intent.putExtra("skb_height", 600);
intent.putExtra("show_input", true);
intent.putExtra("custom_text", new String[]{"id_test", "this is a test"});
intent.putExtra("handle_back_key", true);
intent.putExtra("dim_amount amount", 30);
context.sendBroadcast(intent);

5_2 Skin application structure


The skin application must have the following criteria.
1. The launch options must be set to Nothing, because it won’t have any launcher activity.

2. There must be an activity with the following intent-filter setting:


<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="com.landicorp.pinpad.pinentry.server.SKIN" />
</intent-filter>

Ingenico document - Reproduction or disclosure prohibited without written authorization


20/28 Please check document validity before using
1.1 Development Best Practices Public

The activity here is just a search key for virtual PIN PAD to find the skin application.

3. The application needs a string resource whose id is skin_name. The value insert in this id will
be the name of the skin that will be used in the broadcast. For example, consider the following
skin_name:
<string name="skin_name">TRAINING_SKIN</string>
4. There must be a layout resource whose file name is softkeyboard.xml. This layout will
be loaded and assigned to the virtual PIN PAD, as the UI layout of skin.

5_3 Keyboard layout file


As seen in the previous topic, the keyboard layout must have the name softkeyboard.xml. The
layout is free, but there are some rules to follow:
1. Only Android standard widgets are allowed. Custom views in this layout will cause errors
because the code resource is not loaded.
2. It has to have 13 buttons for each key with the ids: “btn_digit0”, “btn_digit1”, “btn_digit2”,
“btn_digit3”, “btn_digit4”, “btn_digit5”, “btn_digit6”, “btn_digit7”, “btn_digit8”, “btn_digit9”,
“btn_enter”, “btn_cancel” and “btn_clear”.
3. There must have a text view with id “input”. It will be used to show “*” characters representing
every PIN number typed in.
The number shown in the button labels btn_digit0 to btn_digit9 will be produced randomly by virtual
PINPAD and it isn’t related to its id (btn_digit0 may not show the 0 number). Thus, there is no need to
set the android:text field. If this field is set, it will still be overridden by the virtual PINPAD.
Additionally, DON’T set the button background as a texted picture, as it may confuse user.
If all three conditions above has been followed, the application will be treated as a skin and will be
loaded by virtual PINPAD. Any failure may cause this skin to become unavailable.

Extra text view


The layout may have extra text box to receive messages. The application can write in this extra text
view by setting the broadcast extra field called custom_text. For example, let’s suppose the keyboard
layout has an extra text view to show the transaction amount. Then, the application must broadcast an
intent like this:
Intent intent = new Intent(PinSkin.SET_SKIN_ACTION);
String strAmount = String.format("$ %.2f", amount / 100.);
intent.putExtra(SKIN_NAME, skinName);
intent.putExtra(CUSTOM_TEXT, new String[]{"amount", strAmount});
context.sendBroadcast(intent);

Hints
User can set the virtual PIN PAD size programmatically by their will. Then, when you have your
softkeyboard.xml layout, please keep in mind to let it fit for different sizes. You can follow these rules
below to prevent display problems:
 Avoid using specific sizes: using values like “300dp” or “wrap_content” is not
recommended. It’s suggested to use “match_parent” or “android:layout_weight” to set
the size of every widget.
 Use stretchable drawable: nine patch is a good choice or consider to use color, shape or vector
instead if the picture is simple.
 The text size of number buttons and text view: virtual PIN PAD will calculate a suitable text size
for number buttons and text view. You can trim the display effect by set the padding of these views.
All the other views will keep their text size as original set in layout.

Ingenico document - Reproduction or disclosure prohibited without written authorization


21/28 Please check document validity before using
1.1 Development Best Practices Public

 Text view visibility: the text view can be set to View.VISIBLE or View.GONE programmatically
by user, so make sure the layout can be displayed well with or without text view.

5_4 Built-in settings


The skin module can have some built-in settings to set to virtual PIN PAD when this skin is enabled. If
user does not set these via broadcast, these built-in settings will take effect. The priority settings is:
broadcast setting > skin built-in settings > virtual PIN PAD default settings. Any built-in setting is
optional. To add default settings, the application must have a config.xml file in res/values project
directory. The content of this file may have:

/ Config.xml content parameters


Setting Type Description
Integer This value shows which SKIN STRUCTURE version of virtual
version PIN PAD this skin can run onto. The virtual PIN PAD will just
load those skins who have the right version.
is_default Boolean If true, then this skin will be treated as a default skin. A default
skin will automatically be enabled by virtual PIN PAD, the
application will not need to call via broadcast. If there have
multiple default skins installed, virtual will automatically choose
one of them to enable.
If this value does not exist, it will be treated as false.
gravity Integer The location of the virtual PIN PAD.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is Gravity.BOTTOM.
skb_x Integer The X-pixel coordinate of the virtual PIN PAD.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is 0.
skb_y Integer The Y-pixel coordinate of the virtual PIN PAD.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is 0.
skb_width Integer The width of the virtual PIN PAD, ranging from -1 to MAX.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is -1.
skb_height Integer The height of the virtual PIN PAD, ranging from -1 to MAX.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is 600.
show_input Boolean Whether to show the text view or not.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is true.
handle_back_key Boolean Whether to handle back key of the device.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is true.
dim_amount Integer The alpha of virtual PIN PAD dim. The range goes from 0, that is
[0, 100] transparent setting, to 100 will be all black.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is 30.

Ingenico document - Reproduction or disclosure prohibited without written authorization


22/28 Please check document validity before using
1.1 Development Best Practices Public

disorder Boolean Whether the number keys will be randomly displayed. If true, the
number keys on PIN input will show in random order. If false, the
skin will request the virtual PIN PAD to show as the id order
(btn_digit0 will show 0, btn_digit1 will show 1, and so on). To be
PCI compliant, this setting should be set to true.
If this value does not exist, it will use the virtual PIN PAD default
settings instead that is true.

Content example
This is an example for config.xml file.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="version">1</integer>
<bool name="is_default">false</bool>
<integer name="gravity">80</integer><!-- 80 is the value of Gravity.BOTTOM -->
<integer name="skb_x">720</integer>
<integer name="skb_y">0</integer>
<integer name="skb_width">720</integer>
<integer name="skb_height">860</integer>
<bool name="show_input">true</bool>
<bool name="handle_back_key">false</bool>
<integer name="dim_amount">80</integer>
<string name="password_char">&#9679;</string>
<bool name="disorder">false</bool>
</resources>

5_5 Package name of the skin module


The developer is free to define any package name. However, when it starts with
“com.landicopr.pinpad.skin”, it will be automatically loaded after it’s installed because the
virtual PIN PAD always listens to installations of this sort of APKs. Otherwise, the device need to be
rebooted to load the new skin.

Ingenico document - Reproduction or disclosure prohibited without written authorization


23/28 Please check document validity before using
1.1 Development Best Practices Public

6 Visual impaired settings


APOS A8 shipped with USDK version 2.3.0 or above provides two types of virtual PIN PAD: normal
PIN PAD and visual impaired PIN PAD (VI PIN PAD). The VI PIN PAD requires the terminal supports
non-randomized PIN entry.

Figure 1 : normal PIN PAD Figure 2 : visual impaired PIN PAD

A default VI PIN skin is available in OS version 6.4.84 or above. To change to the default VI PIN skin,
just send a broadcast like the snippet below:
intent = new Intent("com.landicorp.pinpad.pinentry.server.SET_SKIN");
intent.putExtra("skin_name", "VIPIN_DEFAULT");
context.sendBroadcast(intent);

The APOS A8 is delivered with a transparent plastic frame (Figure 3) with embossed numbers. This
frame is to attach to the touch screen to use along with the default VI PIN skin helping visual impaired
cardholder locate the numbers.

Ingenico document - Reproduction or disclosure prohibited without written authorization


24/28 Please check document validity before using
1.1 Development Best Practices Public

Figure 3 – transparent plastic frame

6_1 Using USDK


This topic covers application that integrates directly to USDK library and it’s based on version 2.3.10.
To set the visual impaired mode, the application must pay attention to two method: startPinEntry
and setPinEntryExtraConfg.

Extra settings method


The method setPinEntryExtraConfig sets additional configuration information of the PIN input
process, valid for the current PIN PAD instance, and it affects only the next PIN input behavior. It
takes a Bundle object as an input parameter that may comprises the following settings.

/ Extra settings
Name Type Description
PIN trigger mode, that is, the action the cardholder uses to
input a number. The possible values are:
 0 – normal mode (default)
 1 – long press
pin_trigger_mode Integer
 2 – long press and release the key
 4 – double tap
 5 – double tap or long press
 6 – double tap or long press and release the key
Long press timeout. Default value is 2000 ms, don't exceed
t_long_down_ms Integer
10000 ms.
Double click time release. Default value is 1000 ms, don't
t_up_ms Integer
exceed 10000.

Ingenico document - Reproduction or disclosure prohibited without written authorization


25/28 Please check document validity before using
1.1 Development Best Practices Public

Double click time pressing, Default value is 1000 ms, don't


t_down_ms Integer exceed 10000 ms and it must be less than
t_long_down_ms.
hits_num Integer Multi-click mode. Default value is 2.

The most important parameter is the trigger mode, and it should be set any value other than the
default.

Start PIN entry method


The second parameter is a Bundle object with several parameters. The parameter reactionMode is
optional and represents the response mode to the PIN input action of the user. It is an integer variable
whose values is represented by bit masks. The important bit for VI mode is the constant
ReactionMode.ENABLE_VISUALLY_IMPAIRED_MODE (value is -2147483648). However,
depending on the OTA, this parameter became deprecated and the application should use the VI PIN
skin along with the method setPinExtraConfig.

6_2 Using BC APOS


This topic covers application that integrates directly to BCAPOS library and it’s based on version 4.16.
To set the VI mode, the application must send a Bundle object to the setProperties method, in
Pinpad class. The values for this object are the same detailed in topic 6_1_1, and at least the trigger
mode should be set.

6_3 Audio feedback


The virtual PIN PAD does not provide any audio feedback, like a beep for every key typed in because
it would not be compliant to PCI requirements. As this kind of feedback is important for visual impaired
people, the application should do it by beeping for every PIN entry interaction.

Ingenico document - Reproduction or disclosure prohibited without written authorization


26/28 Please check document validity before using
1.1 Development Best Practices Public

7 Development hints
Here we will see some hints to help the development process.

7_1 Inserting test encryption keys


When executing a card transaction, it may need to enter a cardholder PIN to go online, and it implies
in having a 3DES master key (MK) or DUKPT 3DES parameter. If it is running in a mockup device and
there will be no PIN decryption and validation, the application may insert any MK or DUPKT parameter
to execute the PIN process. The following code snippet helps how to do this.
try {
UPinpad pinpad = DeviceHelper.me().getPinpad(0, 0, KeySystem.KS_MKSK);
pinpad.open();
try {
// index 4
pinpad.loadPlainTextKey(KeyType.MAIN_KEY, 4, new byte[]{0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22});
// index 10
pinpad.loadPlainTextKey(KeyType.MAIN_KEY, 10, pinpad.getRandom(16));
} finally {
pinpad.close();
}

pinpad = DeviceHelper.me().getPinpad(0, 0, KeySystem.KS_DUKPT);


pinpad.open();
try {
// index 10
pinpad.loadPlainTextKey(KeyType.MAIN_KEY, 10, pinpad.getRandom(16));
pinpad.initDukptIkKsn(10, new byte[10]);
} finally {
pinpad.close();
}
} catch (RemoteException e) {
}
In this example, the application is injecting two MK and one DUKPT in the KAP ID (0, 0), because this
is the only KAPI ID available in mockup devices.

Mapping KAP ID to BC
The previous code sample is inserting keys into KAP ID area, that is the logical area native to APOS
A8. However, when using BC, the index keys are different, and they are based on ABECS key map.
The BC APOS library maps a position in the KAP ID to a position in the BC map. The table below
shows the association between them in order to help developers where to insert a key to test in
mockup devices. Note that not all BC index are mapped to a KAP ID.

/ BC to KAP ID mapping
KAP ID (0,0) index
BC index
3DES DUKPT

Ingenico document - Reproduction or disclosure prohibited without written authorization


27/28 Please check document validity before using
1.1 Development Best Practices Public

3DES PIN 3DES Data DUKPT PIN DUKPT Data

1 - - 4 5

2 4 5 3 28

3 1 - 2 -

4 0 55 - -

8 24 7 8 7

9 26 54 - -

10 2 3 22 23

11 - - 24 27

12 32 33 - -

13 34 35 - -

14 36 37 11 12

15 38 39 25 26

16 - - 13 14

17 - 6 6 -

18 44 45 15 16

19 - 47 17 18

20 - - 0 1

21 - 51 19 -

22 52 53 20 21

Ingenico document - Reproduction or disclosure prohibited without written authorization


28/28 Please check document validity before using

You might also like