From a4fc6b4e5e0a22a3969f8b0c1d3c0cf8a37921e0 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Tue, 6 Aug 2024 23:47:44 +0200 Subject: [PATCH] IFAAService: Add null checks Change-Id: Ia26b799b29d0d3157253512497160c48c877e7f9 --- IFAAService/Android.bp | 2 +- .../org/ifaa/aidl/manager/IfaaService.java | 207 ------------------ .../src/org/ifaa/aidl/manager/IfaaService.kt | 183 ++++++++++++++++ 3 files changed, 184 insertions(+), 208 deletions(-) delete mode 100644 IFAAService/src/org/ifaa/aidl/manager/IfaaService.java create mode 100644 IFAAService/src/org/ifaa/aidl/manager/IfaaService.kt diff --git a/IFAAService/Android.bp b/IFAAService/Android.bp index f58edd9..914d556 100644 --- a/IFAAService/Android.bp +++ b/IFAAService/Android.bp @@ -7,7 +7,7 @@ android_app { name: "IFAAService", srcs: [ - "src/**/*.java", + "src/**/*.kt", "src/**/*.aidl", ], aidl: { diff --git a/IFAAService/src/org/ifaa/aidl/manager/IfaaService.java b/IFAAService/src/org/ifaa/aidl/manager/IfaaService.java deleted file mode 100644 index 547864c..0000000 --- a/IFAAService/src/org/ifaa/aidl/manager/IfaaService.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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 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 && - SystemProperties.getBoolean("ro.hardware.fp.udfps", false)) { - 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.udfps.location.X_Y", ""); - String wh = SystemProperties.get("persist.vendor.sys.fp.udfps.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(","); - } -} diff --git a/IFAAService/src/org/ifaa/aidl/manager/IfaaService.kt b/IFAAService/src/org/ifaa/aidl/manager/IfaaService.kt new file mode 100644 index 0000000..dc89544 --- /dev/null +++ b/IFAAService/src/org/ifaa/aidl/manager/IfaaService.kt @@ -0,0 +1,183 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 The LineageOS Project + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.ifaa.aidl.manager + +import android.app.Service +import android.content.Intent +import android.os.Build +import android.os.IHwBinder +import android.os.SystemProperties +import android.provider.Settings +import android.util.Log +import org.ifaa.aidl.manager.IfaaManagerService +import org.json.JSONObject +import vendor.xiaomi.hardware.mlipay.V1_1.IMlipayService + +class IfaaService : Service() { + private var _mlipayService: IMlipayService? = null + + private val mlipayServiceDeathRecipient = IHwBinder.DeathRecipient { + Log.i(LOG_TAG, "mlipay service died") + _mlipayService = null + } + + private val mBinder = object : IfaaManagerService.Stub() { + override fun getSupportBIOTypes(): Int { + val fpVendor = SystemProperties.get(FP_VENDOR_PROP, "") + val isUdfps = SystemProperties.getBoolean(IS_UDFPS_PROP, false) + + val supportedBioMask = when (!invalidFpVendors.contains(fpVendor.lowercase())) { + true -> AUTH_TYPE_FINGERPRINT or AUTH_TYPE_IRIS + else -> AUTH_TYPE_IRIS + } + + val ifaaProp = SystemProperties.getInt( + SUPPORTED_BIO_MASK_PROP, 0 + ) and supportedBioMask or when (isUdfps) { + true -> AUTH_TYPE_OPTICAL_FINGERPRINT + else -> 0 + } + + return ifaaProp + } + + override fun startBIOManager(authType: Int) = when (authType) { + AUTH_TYPE_FINGERPRINT -> { + val intent = Intent(Settings.ACTION_SECURITY_SETTINGS).apply { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + + applicationContext.startActivity(intent) + + COMMAND_OK + } + + else -> COMMAND_FAIL + } + + override fun getDeviceModel() = "${Build.MANUFACTURER}-${Build.DEVICE}" + + override fun processCmd(param: ByteArray) = getMlipayService()?.let { mlipayService -> + var receiveBuffer: ByteArray? = null + + val paramByteArray = ArrayList().apply { + for (byte in param) { + add(byte) + } + } + + try { + val receiveBufferByteArray = mlipayService.invoke_command( + paramByteArray, paramByteArray.size + ) + + receiveBuffer = receiveBufferByteArray.toByteArray() + } catch (e: Exception) { + Log.e(LOG_TAG, "processCmdImpl: mlipay invoke_command failed", e) + } + + receiveBuffer + } + + override fun getVersion() = 4 + + override fun getExtInfo(authType: Int, keyExtInfo: String) = initExtString() + + override fun setExtInfo(authType: Int, keyExtInfo: String, valExtInfo: String) { + // Do nothing + } + + override fun getEnabled(bioType: Int) = when (bioType) { + AUTH_TYPE_FINGERPRINT -> BIOMETRICS_AVAILABLE + else -> SCREEN_LOCK_NONE + } + + override fun getIDList(bioType: Int): IntArray { + var idList = IntArray(0) + + getMlipayService()?.let { mlipayService -> + try { + val idListAL = mlipayService.ifaa_get_idlist(bioType) + + idList = idListAL.toIntArray() + } catch (e: Exception) { + Log.e(LOG_TAG, "getIDListImpl: mlipay ifaa_get_idlist failed", e) + } + } + + return idList + } + } + + override fun onBind(intent: Intent) = mBinder + + private fun getMlipayService() = _mlipayService ?: runCatching { + IMlipayService.getService(true) + }.onSuccess { + _mlipayService = it + it.linkToDeath(mlipayServiceDeathRecipient, 0) + }.getOrNull() + + private fun initExtString(): String { + val obj = JSONObject() + val keyInfo = JSONObject() + + val xy = SystemProperties.get(UDFPS_LOCATION_X_Y_PROP, "") + val wh = SystemProperties.get(UDFPS_SIZE_W_H_PROP, "") + + try { + if (!validateVal(xy) || !validateVal(wh)) { + Log.e(LOG_TAG, "initExtString: invalidate, xy: $xy, wh: $wh") + return "" + } + + val split = xy.split(",") + val split2 = wh.split(",") + + keyInfo.put("startX", split[0].toInt()) + keyInfo.put("startY", split[1].toInt()) + keyInfo.put("width", split2[0].toInt()) + keyInfo.put("height", split2[1].toInt()) + keyInfo.put("navConflict", true) + + obj.put("type", 0) + obj.put("fullView", keyInfo) + + return obj.toString() + } catch (e: Exception) { + Log.e(LOG_TAG, "initExtString: Exception, xy: $xy, wh: $wh", e) + return "" + } + } + + private fun validateVal(str: String) = !"".equals(str, ignoreCase = true) && str.contains(",") + + companion object { + private val LOG_TAG = IfaaService::class.simpleName!! + + private const val AUTH_TYPE_NOT_SUPPORT = 0 + private const val AUTH_TYPE_FINGERPRINT = 1 + private const val AUTH_TYPE_IRIS = 1.shl(1) + private const val AUTH_TYPE_OPTICAL_FINGERPRINT = 1.shl(2) + + private const val BIOMETRICS_AVAILABLE = 1000 + private const val SCREEN_LOCK_NONE = 1003 + + private const val COMMAND_OK = 0 + private const val COMMAND_FAIL = -1 + + private const val SUPPORTED_BIO_MASK_PROP = "persist.vendor.sys.pay.ifaa" + private const val FP_VENDOR_PROP = "persist.vendor.sys.fp.vendor" + private const val IS_UDFPS_PROP = "ro.hardware.fp.udfps" + private const val UDFPS_LOCATION_X_Y_PROP = "persist.vendor.sys.fp.udfps.location.X_Y" + private const val UDFPS_SIZE_W_H_PROP = "persist.vendor.sys.fp.udfps.size.width_height" + + private val invalidFpVendors = arrayOf( + "", + "none", + ) + } +}