Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Merge pull request #34 from minggangw/fingerprint
Browse files Browse the repository at this point in the history
[Fingerprint]Implement the fingerprint authentication on Android
  • Loading branch information
Halton Huo committed Feb 22, 2016
2 parents e6dd0af + 961fb86 commit 158838e
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ language: android
android:
components:
- build-tools-22.0.1
- android-22
- android-23

env:
matrix:
Expand Down Expand Up @@ -40,6 +40,7 @@ install:

before_deploy:
- zip -j iap.zip out/Default/gen/iap/iap.jar out/Default/gen/iap/iap.js out/Default/gen/iap/iap.json
- zip -j fingerprint.zip out/Default/gen/fingerprint/fingerprint.jar out/Default/gen/fingerprint/fingerprint.js out/Default/gen/fingerprint/fingerprint.json

deploy:
provider: releases
Expand All @@ -57,6 +58,7 @@ script:
- cd crosswalk-android-extensions
- gyp --depth=. all.gyp
- ninja -C out/Default pack_iap_jars
- ninja -C out/Default fingerprint

notifications:
email:
Expand Down
1 change: 1 addition & 0 deletions all.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'ad/ad.gyp:*',
'ardrone_pilot/ardrone_pilot.gyp:*',
'ardrone_video/ardrone_video.gyp:*',
'fingerprint/fingerprint.gyp:*',
'iap/iap.gyp:*',
'idl_demo/idl_demo.gyp:*',
],
Expand Down
26 changes: 26 additions & 0 deletions fingerprint/fingerprint.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2016 Intel Corporation. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

{
'includes':[
'../build/common.gypi',
],

'targets': [
{
'target_name': 'fingerprint',
'type': 'none',
'variables': {
'java_in_dir': '<(DEPTH)/fingerprint',
'js_file': 'fingerprint.js',
'json_file': 'fingerprint.json',
'input_jars_paths': [
'<(core_library_java_jar)',
'<(android_jar)',
],
},
'includes': [ '../build/java.gypi' ],
},
],
}
45 changes: 45 additions & 0 deletions fingerprint/fingerprint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2016 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var g_asyncRequests = {};
var g_nextRequestId = 0;

function AsyncRequest(resolve, reject) {
this.resolve = resolve;
this.reject = reject;
}

function createAsyncRequest(resolve, reject) {
var requestId = ++g_nextRequestId;
var asyncRequest = new AsyncRequest(resolve, reject);
g_asyncRequests[requestId] = asyncRequest;

return requestId;
}

function sendAsycRequest(command, requestId, message) {
var message = { "cmd": command, "requestId": requestId, "data": message };
extension.postMessage(JSON.stringify(message));
}

exports.authenticate = function(reason) {
return new Promise(function(resolve, reject) {
var requestId = createAsyncRequest(resolve, reject);
sendAsycRequest("authenticate", requestId, reason);
});
}

extension.setMessageListener(function(json) {
var msg = JSON.parse(json);
var request = g_asyncRequests[msg.requestId];

if (request) {
if (msg.error) {
request.reject.apply(null, [msg.error]);
} else {
request.resolve.apply(null, [msg.data]);
}
delete g_asyncRequests[msg.requestId];
}
});
5 changes: 5 additions & 0 deletions fingerprint/fingerprint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "xwalk.experimental.fingerprint",
"class": "org.xwalk.extensions.FingerprintExtension",
"jsapi": "fingerprint.js"
}
137 changes: 137 additions & 0 deletions fingerprint/src/org/xwalk/extensions/FingerprintExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright (c) 2016 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.xwalk.extensions;

import android.hardware.fingerprint.FingerprintManager;
import android.os.CancellationSignal;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import org.xwalk.core.extension.XWalkExtensionContextClient;
import org.xwalk.core.extension.XWalkExternalExtension;

public class FingerprintExtension extends XWalkExternalExtension {
private final FingerprintManager mFingerprintManager;
private CancellationSignal mCancellationSignal;
private boolean mAuthenticating = false;
private int mRequestId;
private int mInstanceId;

// The names of errors.
public static final String OPERATION_ERROR = "OperationError";
public static final String NOT_SUPPORT_ERROR = "NotSupportError";

// Command used by this extension.
private static final String CMD_AUTHENTICATE = "authenticate";

private static final String TAG = "Fingerprint";

public FingerprintExtension(String extensionName, String jsApi, XWalkExtensionContextClient context) {
super(extensionName, jsApi, context);
mFingerprintManager = context.getContext().getSystemService(FingerprintManager.class);
}

public boolean isFingerprintAvailable() {
return mFingerprintManager.isHardwareDetected() && mFingerprintManager.hasEnrolledFingerprints();
}

@Override
public void onMessage(int instanceId, String message) {
try {
JSONObject object = new JSONObject(message);

String cmd = object.getString("cmd");
int requestId = object.getInt("requestId");

Log.e(TAG, "Receive command: " + cmd);
if (cmd.equals(CMD_AUTHENTICATE)) {
if (!isFingerprintAvailable()) {
postErrorMessage(instanceId, requestId, NOT_SUPPORT_ERROR);
return;
}

if (mAuthenticating) {
Log.e(TAG, "Error: Authentication is already running.");
postErrorMessage(instanceId, requestId, OPERATION_ERROR);
return;
}

mInstanceId = instanceId;
mRequestId = requestId;
mAuthenticating = true;
mCancellationSignal = new CancellationSignal();
mFingerprintManager.authenticate(null, mCancellationSignal, 0, mAuthenticationCallback, null);
} else {
Log.e(TAG, "Unexpected command received: " + cmd);
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
}
}

protected void postErrorMessage(int instanceId, int requestId, String errorName) {
try {
JSONObject error = new JSONObject();
error.put("name", errorName);
JSONObject object = new JSONObject();
object.put("requestId", requestId);
object.put("error", error);
postMessage(instanceId, object.toString());
} catch (JSONException e) {
Log.e(TAG, e.toString());
}
}

protected void postSuccessMessage(int instanceId, int requestId) {
try {
JSONObject object = new JSONObject();
object.put("requestId", mRequestId);
postMessage(mInstanceId, object.toString());
} catch (JSONException e) {
Log.e(TAG, e.toString());
}
}

protected void stopAuthenticating() {
if (mCancellationSignal != null) {
mCancellationSignal.cancel();
mCancellationSignal = null;
}
mAuthenticating = false;
}

private FingerprintManager.AuthenticationCallback mAuthenticationCallback =
new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
postErrorMessage(mInstanceId, mRequestId, OPERATION_ERROR);
stopAuthenticating();
Log.e(TAG, "Error: errorCode = " + errorCode);
}

@Override
public void onAuthenticationFailed() {
postErrorMessage(mInstanceId, mRequestId, OPERATION_ERROR);
stopAuthenticating();
Log.e(TAG, "Error: Authentication Failed.");
}

@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
postSuccessMessage(mInstanceId, mRequestId);
mAuthenticating = false;
Log.e(TAG, "Authentication Succeeded.");
}

@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
postErrorMessage(mInstanceId, mRequestId, OPERATION_ERROR);
stopAuthenticating();
Log.e(TAG, "Error: errorCode = " + helpCode);
}
};
}

0 comments on commit 158838e

Please sign in to comment.