This repository has been archived by the owner on Jan 12, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 534
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
858 additions
and
162 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Test Card Images | ||
|
||
Card images in this folder are included for automated testing. Images should be 640px x 480px for | ||
tests. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
113 changes: 113 additions & 0 deletions
113
SampleApp/src/androidTest/java/io/card/payment/CardScannerTester.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package io.card.payment; | ||
|
||
/* CardScannerTester.java | ||
* See the file "LICENSE.md" for the full license governing this code. | ||
*/ | ||
|
||
import android.graphics.Bitmap; | ||
import android.graphics.BitmapFactory; | ||
import android.os.Handler; | ||
import android.view.SurfaceHolder; | ||
|
||
import java.io.IOException; | ||
|
||
import static android.support.test.InstrumentationRegistry.getInstrumentation; | ||
|
||
public class CardScannerTester extends CardScanner { | ||
|
||
private static final long FRAME_INTERVAL = (long) (1000.0 / 30); | ||
|
||
private static String sCardAssetName; | ||
|
||
private boolean mScanAllowed; | ||
private Handler mHandler; | ||
private byte[] mFrame; | ||
|
||
public static void setCardAsset(String cardAssetName) { | ||
sCardAssetName = cardAssetName; | ||
} | ||
|
||
public CardScannerTester(CardIOActivity scanActivity, int currentFrameOrientation) { | ||
super(scanActivity, currentFrameOrientation); | ||
useCamera = false; | ||
mScanAllowed = false; | ||
mHandler = new Handler(); | ||
|
||
try { | ||
Bitmap bitmap = BitmapFactory.decodeStream(getInstrumentation().getContext().getAssets() | ||
.open("test_card_images/" + sCardAssetName)); | ||
mFrame = getNV21FormattedImage(bitmap.getWidth(), bitmap.getHeight(), bitmap); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private Runnable mFrameRunnable = new Runnable() { | ||
@Override | ||
public void run() { | ||
if (!mScanAllowed) { | ||
return; | ||
} | ||
|
||
onPreviewFrame(mFrame, null); | ||
mHandler.postDelayed(this, FRAME_INTERVAL); | ||
} | ||
}; | ||
|
||
@Override | ||
boolean resumeScanning(SurfaceHolder holder) { | ||
boolean result = super.resumeScanning(holder); | ||
mScanAllowed = true; | ||
mHandler.postDelayed(mFrameRunnable, FRAME_INTERVAL); | ||
return result; | ||
} | ||
|
||
@Override | ||
public void pauseScanning() { | ||
mScanAllowed = false; | ||
super.pauseScanning(); | ||
} | ||
|
||
private byte[] getNV21FormattedImage(int width, int height, Bitmap bitmap) { | ||
int [] argb = new int[width * height]; | ||
byte [] yuv = new byte[width * height * 3 / 2]; | ||
|
||
bitmap.getPixels(argb, 0, width, 0, 0, width, height); | ||
encodeYUV420SP(yuv, argb, width, height); | ||
bitmap.recycle(); | ||
|
||
return yuv; | ||
} | ||
|
||
private void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) { | ||
int frameSize = width * height; | ||
int yIndex = 0; | ||
int uvIndex = frameSize; | ||
|
||
int R, G, B, Y, U, V; | ||
int index = 0; | ||
for (int j = 0; j < height; j++) { | ||
for (int i = 0; i < width; i++) { | ||
R = (argb[index] & 0xff0000) >> 16; | ||
G = (argb[index] & 0xff00) >> 8; | ||
B = (argb[index] & 0xff); | ||
|
||
// well known RGB to YUV algorithm | ||
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16; | ||
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128; | ||
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128; | ||
|
||
// NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2 | ||
// meaning for every 4 Y pixels there are 1 V and 1 U. Note the sampling is every | ||
// other pixel AND every other scanline. | ||
yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y)); | ||
if (j % 2 == 0 && index % 2 == 0) { | ||
yuv420sp[uvIndex++] = (byte)((V<0) ? 0 : ((V > 255) ? 255 : V)); | ||
yuv420sp[uvIndex++] = (byte)((U<0) ? 0 : ((U > 255) ? 255 : U)); | ||
} | ||
|
||
index ++; | ||
} | ||
} | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
SampleApp/src/androidTest/java/io/card/test/CardIOActivityTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package io.card.test; | ||
|
||
import android.Manifest; | ||
import android.app.Activity; | ||
import android.content.Intent; | ||
|
||
import org.junit.Rule; | ||
import org.junit.Test; | ||
|
||
import java.lang.reflect.Field; | ||
|
||
import io.card.payment.CardIOActivity; | ||
import io.card.payment.CardScannerTester; | ||
import io.card.payment.CreditCard; | ||
|
||
import static com.lukekorth.deviceautomator.DeviceAutomator.onDevice; | ||
import static junit.framework.Assert.assertEquals; | ||
import static org.hamcrest.core.Is.is; | ||
import static org.junit.Assert.assertThat; | ||
|
||
public class CardIOActivityTest { | ||
|
||
private CardIOTestActivity mActivity; | ||
|
||
@Rule | ||
public final CustomActivityTestRule<CardIOTestActivity> mActivityTestRule = | ||
new CustomActivityTestRule<>(CardIOTestActivity.class, false, false); | ||
|
||
@Test(timeout = 30000) | ||
public void scansAmexCards() { | ||
CardScannerTester.setCardAsset("amex.png"); | ||
|
||
startScan(); | ||
|
||
waitForActivityToFinish(); | ||
CreditCard result = getActivityResultIntent().getParcelableExtra(CardIOActivity.EXTRA_SCAN_RESULT); | ||
assertEquals("3743 260055 74998", result.getFormattedCardNumber()); | ||
} | ||
|
||
private void startScan() { | ||
mActivityTestRule.launchActivity(null); | ||
mActivity = mActivityTestRule.getActivity(); | ||
|
||
onDevice().acceptRuntimePermission(Manifest.permission.CAMERA); | ||
} | ||
|
||
private void waitForActivityToFinish() { | ||
long endTime = System.currentTimeMillis() + 10000; | ||
|
||
do { | ||
try { | ||
if (mActivity.isFinishing()) { | ||
return; | ||
} | ||
} catch (Exception ignored) {} | ||
} while (System.currentTimeMillis() < endTime); | ||
|
||
throw new RuntimeException("Maximum wait elapsed (10s) while waiting for activity to finish"); | ||
} | ||
|
||
private Intent getActivityResultIntent() { | ||
assertThat("Activity did not finish", mActivity.isFinishing(), is(true)); | ||
|
||
try { | ||
Field resultDataField = Activity.class.getDeclaredField("mResultData"); | ||
resultDataField.setAccessible(true); | ||
return (Intent) resultDataField.get(mActivity); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
SampleApp/src/androidTest/java/io/card/test/CustomActivityTestRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package io.card.test; | ||
|
||
|
||
import android.app.Activity; | ||
import android.app.KeyguardManager; | ||
import android.content.Context; | ||
|
||
import static android.support.test.InstrumentationRegistry.getTargetContext; | ||
|
||
public class CustomActivityTestRule<T extends Activity> extends android.support.test.rule.ActivityTestRule<T> { | ||
|
||
private KeyguardManager.KeyguardLock mKeyguardLock; | ||
|
||
public CustomActivityTestRule(Class<T> activityClass) { | ||
super(activityClass); | ||
init(); | ||
} | ||
|
||
public CustomActivityTestRule(Class<T> activityClass, boolean initialTouchMode) { | ||
super(activityClass, initialTouchMode); | ||
init(); | ||
} | ||
|
||
public CustomActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) { | ||
super(activityClass, initialTouchMode, launchActivity); | ||
init(); | ||
} | ||
|
||
private void init() { | ||
mKeyguardLock = ((KeyguardManager) getTargetContext().getSystemService(Context.KEYGUARD_SERVICE)) | ||
.newKeyguardLock("CardIOTest"); | ||
mKeyguardLock.disableKeyguard(); | ||
} | ||
|
||
@Override | ||
protected void afterActivityFinished() { | ||
super.afterActivityFinished(); | ||
|
||
mKeyguardLock.reenableKeyguard(); | ||
} | ||
} |
Oops, something went wrong.