From 5eb7d26c52f6c2f512cfd138e641f06fd445b0a2 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Fri, 15 Apr 2022 00:14:19 +0200 Subject: [PATCH] IFAAService: Initial implementation Co-authored-by: Art_Chen Co-authored-by: dianlujitao Change-Id: Ia238f3e82e6366e72de4629b31864d0503dd1a03 --- IFAAService/Android.bp | 26 +++ IFAAService/AndroidManifest.xml | 11 + IFAAService/res/values/strings.xml | 4 + .../ifaa/aidl/manager/IfaaManagerService.aidl | 19 ++ .../org/ifaa/aidl/manager/IfaaService.java | 208 ++++++++++++++++++ 5 files changed, 268 insertions(+) create mode 100644 IFAAService/Android.bp create mode 100644 IFAAService/AndroidManifest.xml create mode 100644 IFAAService/res/values/strings.xml create mode 100644 IFAAService/src/org/ifaa/aidl/manager/IfaaManagerService.aidl create mode 100644 IFAAService/src/org/ifaa/aidl/manager/IfaaService.java diff --git a/IFAAService/Android.bp b/IFAAService/Android.bp new file mode 100644 index 0000000..890cc37 --- /dev/null +++ b/IFAAService/Android.bp @@ -0,0 +1,26 @@ +// +// Copyright (C) 2022 The LineageOS Project +// +// SPDX-License-Identifier: Apache-2.0 +// + +android_app { + name: "IFAAService", + srcs: [ + "src/**/*.java", + "src/**/I*.aidl", + ], + aidl: { + local_include_dirs: ["src"], + }, + resource_dirs: ["res"], + + static_libs: [ + "android.hidl.base-V1.0-java", + "vendor.xiaomi.hardware.mlipay-V1.1-java", + ], + + certificate: "platform", + platform_apis: true, + system_ext_specific: true, +} diff --git a/IFAAService/AndroidManifest.xml b/IFAAService/AndroidManifest.xml new file mode 100644 index 0000000..a98c112 --- /dev/null +++ b/IFAAService/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/IFAAService/res/values/strings.xml b/IFAAService/res/values/strings.xml new file mode 100644 index 0000000..08c41bf --- /dev/null +++ b/IFAAService/res/values/strings.xml @@ -0,0 +1,4 @@ + + + IFAAService + diff --git a/IFAAService/src/org/ifaa/aidl/manager/IfaaManagerService.aidl b/IFAAService/src/org/ifaa/aidl/manager/IfaaManagerService.aidl new file mode 100644 index 0000000..3219834 --- /dev/null +++ b/IFAAService/src/org/ifaa/aidl/manager/IfaaManagerService.aidl @@ -0,0 +1,19 @@ +// +// Copyright (C) 2022 The LineageOS Project +// +// SPDX-License-Identifier: Apache-2.0 +// + +package org.ifaa.aidl.manager; + +interface IfaaManagerService { + int getSupportBIOTypes(); + int startBIOManager(int authType); + String getDeviceModel(); + byte[] processCmd(in byte[] param); + int getVersion(); + String getExtInfo(int authType, String keyExtInfo); + void setExtInfo(int authType, String keyExtInfo, String valExtInfo); + int getEnabled(int bioType); + int[] getIDList(int bioType); +} diff --git a/IFAAService/src/org/ifaa/aidl/manager/IfaaService.java b/IFAAService/src/org/ifaa/aidl/manager/IfaaService.java new file mode 100644 index 0000000..e0c5335 --- /dev/null +++ b/IFAAService/src/org/ifaa/aidl/manager/IfaaService.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2022 The LineageOS Project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.ifaa.aidl.manager; + +import android.app.KeyguardManager; +import android.app.Service; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.hardware.fingerprint.Fingerprint; +import android.hardware.fingerprint.FingerprintManager; +import android.os.Build; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.SystemProperties; +import android.util.Log; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import org.ifaa.aidl.manager.IfaaManagerService; +import org.json.JSONObject; +import org.json.JSONException; +import vendor.xiaomi.hardware.mlipay.V1_1.IMlipayService; + +public class IfaaService extends Service { + private static final String LOG_TAG = IfaaService.class.getSimpleName(); + + private static final int AUTH_TYPE_NOT_SUPPORT = 0; + private static final int AUTH_TYPE_FINGERPRINT = 1; + private static final int AUTH_TYPE_IRIS = 1<<1; + private static final int AUTH_TYPE_OPTICAL_FINGERPRINT = 1<<4; + + private static final int ACTIVITY_START_SUCCESS = 0; + private static final int ACTIVITY_START_FAILED = -1; + + private static boolean sIsFod = SystemProperties.getBoolean("ro.hardware.fp.fod", false); + + private IMlipayService mMlipayService = null; + + private final IBinder mIFAABinder = new IfaaServiceStub(this); + + private final class IfaaServiceStub extends IfaaManagerService.Stub { + IfaaServiceStub(IfaaService ifaaService) { + new WeakReference(ifaaService); + } + + @Override + public int getSupportBIOTypes() { + int ifaaProp = SystemProperties.getInt("persist.vendor.sys.pay.ifaa", 0); + String fpVendor = SystemProperties.get("persist.vendor.sys.fp.vendor", ""); + + int res = "none".equalsIgnoreCase(fpVendor) ? + ifaaProp & AUTH_TYPE_IRIS : + ifaaProp & (AUTH_TYPE_FINGERPRINT | AUTH_TYPE_IRIS); + + if ((res & AUTH_TYPE_FINGERPRINT) == AUTH_TYPE_FINGERPRINT && sIsFod) { + res |= AUTH_TYPE_OPTICAL_FINGERPRINT; + } + + return res; + } + + @Override + public int startBIOManager(int authType) { + int res = ACTIVITY_START_FAILED; + + if (authType == AUTH_TYPE_FINGERPRINT) { + Intent intent = new Intent("android.settings.SECURITY_SETTINGS"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getApplicationContext().startActivity(intent); + res = ACTIVITY_START_SUCCESS; + } + + return res; + } + + @Override + public String getDeviceModel() { + return Build.MANUFACTURER + "-" + Build.DEVICE; + } + + @Override + public byte[] processCmd(byte[] param) { + IMlipayService mlipayService = getMlipayService(); + if (mlipayService == null) { + Log.e(LOG_TAG, "Failed to open mlipay HAL"); + return null; + } + + ArrayList paramByteArray = new ArrayList(); + for (byte b : param) { + paramByteArray.add(Byte.valueOf(b)); + } + + byte[] receiveBuffer = null; + + try { + ArrayList receiveBufferByteArray = mlipayService.invoke_command(paramByteArray, + paramByteArray.size()); + + receiveBuffer = new byte[receiveBufferByteArray.size()]; + for (int i = 0; i < receiveBufferByteArray.size(); i++) { + receiveBuffer[i] = receiveBufferByteArray.get(i).byteValue(); + } + } catch (RemoteException e) { + Log.e(LOG_TAG, "processCmdImpl: mlipay invoke_command failed", e); + } + + return receiveBuffer; + } + + @Override + public int getVersion() { + return 4; + } + + @Override + public String getExtInfo(int authType, String keyExtInfo) { + return initExtString(); + } + + @Override + public void setExtInfo(int authType, String keyExtInfo, String valExtInfo) { + // nothing + } + + @Override + public int getEnabled(int bioType) { + return 1 == bioType ? 1000 : 1003; + } + + @Override + public int[] getIDList(int bioType) { + int[] idList = new int[0]; + + IMlipayService mlipayService = getMlipayService(); + if (mlipayService == null) { + Log.e(LOG_TAG, "getIDListImpl: Failed to open mlipay HAL"); + return idList; + } + + try { + ArrayList idListAL = mlipayService.ifaa_get_idlist(bioType); + idList = new int[idListAL.size()]; + for (int i = 0; i < idListAL.size(); i++) { + idList[i] = idListAL.get(i).intValue(); + } + } catch (RemoteException e) { + Log.e(LOG_TAG, "getIDListImpl: mlipay ifaa_get_idlist failed", e); + } + + return idList; + } + }; + + @Override // android.app.Service + public IBinder onBind(Intent intent) { + return this.mIFAABinder; + } + + // Utils + + private IMlipayService getMlipayService() { + if (mMlipayService == null) { + try { + mMlipayService = IMlipayService.getService(); + } catch (RemoteException e) { + // do nothing + } + } + + return mMlipayService; + } + + private String initExtString() { + JSONObject obj = new JSONObject(); + JSONObject keyInfo = new JSONObject(); + String xy = SystemProperties.get("persist.vendor.sys.fp.fod.location.X_Y", ""); + String wh = SystemProperties.get("persist.vendor.sys.fp.fod.size.width_height", ""); + try { + if (!validateVal(xy) || !validateVal(wh)) { + Log.e(LOG_TAG, "initExtString: invalidate, xy: " + xy + ", wh: " + wh); + return ""; + } + String[] split = xy.split(","); + String[] split2 = wh.split(","); + keyInfo.put("startX", Integer.parseInt(split[0])); + keyInfo.put("startY", Integer.parseInt(split[1])); + keyInfo.put("width", Integer.parseInt(split2[0])); + keyInfo.put("height", Integer.parseInt(split2[1])); + keyInfo.put("navConflict", true); + obj.put("type", 0); + obj.put("fullView", keyInfo); + return obj.toString(); + } catch (Exception e) { + Log.e(LOG_TAG, "initExtString: Exception, xy: " + xy + ", wh: " + wh, e); + return ""; + } + } + + private boolean validateVal(String str) { + return !"".equalsIgnoreCase(str) && str.contains(","); + } +}