diff --git a/app/src/androidTest/java/im/status/hardwallet_lite_android/ExampleInstrumentedTest.java b/app/src/androidTest/java/im/status/hardwallet_lite_android/ExampleInstrumentedTest.java
deleted file mode 100644
index dad4568..0000000
--- a/app/src/androidTest/java/im/status/hardwallet_lite_android/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package im.status.hardwallet_lite_android;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("im.status.hardwallet_lite_android", appContext.getPackageName());
- }
-}
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java b/app/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java
deleted file mode 100644
index 27baabd..0000000
--- a/app/src/main/java/im/status/hardwallet_lite_android/app/MainActivity.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package im.status.hardwallet_lite_android.app;
-
-import android.nfc.NfcAdapter;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import im.status.hardwallet_lite_android.R;
-import im.status.hardwallet_lite_android.io.CardManager;
-
-import java.security.Security;
-
-public class MainActivity extends AppCompatActivity {
- static {
- Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
- }
-
- private NfcAdapter nfcAdapter;
- private CardManager cardManager;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- nfcAdapter = NfcAdapter.getDefaultAdapter(this);
- this.cardManager = new CardManager();
- this.cardManager.start();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (nfcAdapter != null) {
- nfcAdapter.enableReaderMode(this, this.cardManager, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (nfcAdapter != null) {
- nfcAdapter.disableReaderMode(this);
- }
- }
-}
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/io/CardManager.java b/app/src/main/java/im/status/hardwallet_lite_android/io/CardManager.java
deleted file mode 100644
index cd55e41..0000000
--- a/app/src/main/java/im/status/hardwallet_lite_android/io/CardManager.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package im.status.hardwallet_lite_android.io;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.nfc.tech.IsoDep;
-import android.util.Log;
-import im.status.hardwallet_lite_android.wallet.WalletAppletCommandSet;
-import org.spongycastle.util.encoders.Hex;
-
-import java.io.IOException;
-
-public class CardManager extends Thread implements NfcAdapter.ReaderCallback {
- private static final String TAG = "CardManager";
-
- private IsoDep isoDep;
- private boolean isRunning;
-
- public boolean isConnected() {
- return this.isoDep != null && this.isoDep.isConnected();
- }
-
- @Override
- public void onTagDiscovered(Tag tag) {
- this.isoDep = IsoDep.get(tag);
-
- try {
- this.isoDep = IsoDep.get(tag);
- this.isoDep.connect();
- this.isoDep.setTimeout(120000);
- } catch (IOException e) {
- Log.e(TAG, "error connecting to tag");
- }
- }
-
- public void run() {
- boolean connected = this.isConnected();
-
- while(true) {
- boolean newConnected = this.isConnected();
- if (newConnected != connected) {
- connected = newConnected;
- Log.i(TAG, "tag " + (connected ? "connected" : "disconnected"));
-
- if (connected && !isRunning) {
- this.onCardConnected();
- } else {
- this.onCardDisconnected();
- }
- }
-
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
- Log.e(TAG, "error in TagManager thread: " + e.getMessage());
- this.interrupt();
- }
- }
- }
-
- private void onCardConnected() {
- this.isRunning = true;
-
- try {
- CardChannel cardChannel = new CardChannel(this.isoDep);
- // Applet-specific code
- WalletAppletCommandSet cmdSet = new WalletAppletCommandSet(cardChannel);
-
- // First thing to do is selecting the applet on the card.
- cmdSet.select().checkOK();
-
- // In real projects, the pairing key should be saved and used for all new sessions.
- cmdSet.autoPair("WalletAppletTest");
-
- // Opening a Secure Channel is needed for all other applet commands
- cmdSet.autoOpenSecureChannel();
-
- // We send a GET STATUS command, which does not require PIN authentication
- APDUResponse resp = cmdSet.getStatus(WalletAppletCommandSet.GET_STATUS_P1_APPLICATION).checkOK();
-
- // PIN authentication allows execution of privileged commands
- cmdSet.verifyPIN("000000").checkOK();
-
- // Cleanup, in a real application you would not unpair and instead keep the pairing key for successive interactions.
- // We also remove all other pairings so that we do not fill all slots with failing runs. Again in real application
- // this would be a very bad idea to do.
- cmdSet.unpairOthers();
- cmdSet.autoUnpair();
-
- Log.i(TAG, "GET STATUS response: " + Hex.toHexString(resp.getData()));
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- }
-
- this.isRunning = false;
- }
-
- private void onCardDisconnected() {
- this.isRunning = false;
- this.isoDep = null;
- }
-}
diff --git a/app/src/test/java/im/status/hardwallet_lite_android/ExampleUnitTest.java b/app/src/test/java/im/status/hardwallet_lite_android/ExampleUnitTest.java
deleted file mode 100644
index 24683d0..0000000
--- a/app/src/test/java/im/status/hardwallet_lite_android/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package im.status.hardwallet_lite_android;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 47825b2..8d3ef8e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,7 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.0'
+ classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
diff --git a/app/.gitignore b/demo/.gitignore
similarity index 100%
rename from app/.gitignore
rename to demo/.gitignore
diff --git a/app/build.gradle b/demo/build.gradle
similarity index 77%
rename from app/build.gradle
rename to demo/build.gradle
index 471fe28..a3f84b6 100644
--- a/app/build.gradle
+++ b/demo/build.gradle
@@ -3,7 +3,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
- applicationId "im.status.hardwallet_lite_android"
+ applicationId "im.status.hardwallet_lite_android.demo"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
@@ -19,11 +19,11 @@ android {
}
dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
- implementation 'com.madgag.spongycastle:core:1.58.0.0'
- implementation 'com.madgag.spongycastle:prov:1.58.0.0'
+
+ implementation project(':lib')
+
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
diff --git a/app/proguard-rules.pro b/demo/proguard-rules.pro
similarity index 100%
rename from app/proguard-rules.pro
rename to demo/proguard-rules.pro
diff --git a/app/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml
similarity index 77%
rename from app/src/main/AndroidManifest.xml
rename to demo/src/main/AndroidManifest.xml
index 6cedd88..d1d1a3d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/demo/src/main/AndroidManifest.xml
@@ -1,9 +1,6 @@
-
-
-
+ package="im.status.hardwallet_lite_android.demo">
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/io/APDUCommand.java b/lib/src/main/java/im/status/hardwallet_lite_android/io/APDUCommand.java
similarity index 100%
rename from app/src/main/java/im/status/hardwallet_lite_android/io/APDUCommand.java
rename to lib/src/main/java/im/status/hardwallet_lite_android/io/APDUCommand.java
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/io/APDUException.java b/lib/src/main/java/im/status/hardwallet_lite_android/io/APDUException.java
similarity index 100%
rename from app/src/main/java/im/status/hardwallet_lite_android/io/APDUException.java
rename to lib/src/main/java/im/status/hardwallet_lite_android/io/APDUException.java
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/io/APDUResponse.java b/lib/src/main/java/im/status/hardwallet_lite_android/io/APDUResponse.java
similarity index 100%
rename from app/src/main/java/im/status/hardwallet_lite_android/io/APDUResponse.java
rename to lib/src/main/java/im/status/hardwallet_lite_android/io/APDUResponse.java
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/io/CardChannel.java b/lib/src/main/java/im/status/hardwallet_lite_android/io/CardChannel.java
similarity index 100%
rename from app/src/main/java/im/status/hardwallet_lite_android/io/CardChannel.java
rename to lib/src/main/java/im/status/hardwallet_lite_android/io/CardChannel.java
diff --git a/lib/src/main/java/im/status/hardwallet_lite_android/io/CardManager.java b/lib/src/main/java/im/status/hardwallet_lite_android/io/CardManager.java
new file mode 100644
index 0000000..883f6ee
--- /dev/null
+++ b/lib/src/main/java/im/status/hardwallet_lite_android/io/CardManager.java
@@ -0,0 +1,76 @@
+package im.status.hardwallet_lite_android.io;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.tech.IsoDep;
+import android.os.SystemClock;
+import android.util.Log;
+import java.io.IOException;
+import java.security.Security;
+
+public class CardManager extends Thread implements NfcAdapter.ReaderCallback {
+
+ public CardManager() {
+ Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
+ }
+
+ private static final String TAG = "CardManager";
+
+ private IsoDep isoDep;
+ private boolean isRunning;
+ private OnCardConnectedListener onCardConnectedListener;
+
+ public boolean isConnected() {
+ return isoDep != null && isoDep.isConnected();
+ }
+
+ @Override
+ public void onTagDiscovered(Tag tag) {
+ isoDep = IsoDep.get(tag);
+
+ try {
+ isoDep = IsoDep.get(tag);
+ isoDep.connect();
+ isoDep.setTimeout(120000);
+ } catch (IOException e) {
+ Log.e(TAG, "error connecting to tag");
+ }
+ }
+
+ public void run() {
+ boolean connected = isConnected();
+
+ while (true) {
+ boolean newConnected = isConnected();
+ if (newConnected != connected) {
+ connected = newConnected;
+ Log.i(TAG, "tag " + (connected ? "connected" : "disconnected"));
+
+ if (connected && !isRunning) {
+ onCardConnected();
+ } else {
+ onCardDisconnected();
+ }
+ }
+
+ SystemClock.sleep(50);
+ }
+ }
+
+ private void onCardConnected() {
+ isRunning = true;
+
+ onCardConnectedListener.onConnected(new CardChannel(isoDep));
+
+ isRunning = false;
+ }
+
+ private void onCardDisconnected() {
+ isRunning = false;
+ isoDep = null;
+ }
+
+ public void setOnCardConnectedListener(OnCardConnectedListener onConnectedListener) {
+ onCardConnectedListener = onConnectedListener;
+ }
+}
diff --git a/lib/src/main/java/im/status/hardwallet_lite_android/io/OnCardConnectedListener.java b/lib/src/main/java/im/status/hardwallet_lite_android/io/OnCardConnectedListener.java
new file mode 100644
index 0000000..2c368bf
--- /dev/null
+++ b/lib/src/main/java/im/status/hardwallet_lite_android/io/OnCardConnectedListener.java
@@ -0,0 +1,5 @@
+package im.status.hardwallet_lite_android.io;
+
+public interface OnCardConnectedListener {
+ void onConnected(CardChannel channel);
+}
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/wallet/SecureChannelSession.java b/lib/src/main/java/im/status/hardwallet_lite_android/wallet/SecureChannelSession.java
similarity index 100%
rename from app/src/main/java/im/status/hardwallet_lite_android/wallet/SecureChannelSession.java
rename to lib/src/main/java/im/status/hardwallet_lite_android/wallet/SecureChannelSession.java
diff --git a/app/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java b/lib/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java
similarity index 100%
rename from app/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java
rename to lib/src/main/java/im/status/hardwallet_lite_android/wallet/WalletAppletCommandSet.java
diff --git a/settings.gradle b/settings.gradle
index e7b4def..7f35a15 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,2 @@
-include ':app'
+include ':lib'
+include ':demo'