diff --git a/patches/platform_frameworks_base/0054-Allow-disabling-of-fingerprint-cleanups-needed-on-so.patch b/patches/platform_frameworks_base/0054-Allow-disabling-of-fingerprint-cleanups-needed-on-so.patch new file mode 100644 index 0000000..a880a22 --- /dev/null +++ b/patches/platform_frameworks_base/0054-Allow-disabling-of-fingerprint-cleanups-needed-on-so.patch @@ -0,0 +1,40 @@ +From b0d4bdf42853edee3ee12acf269c8891af63060c Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Tue, 10 Mar 2020 23:30:17 +0100 +Subject: [PATCH 54/55] Allow disabling of fingerprint cleanups, needed on some + Realme devices that cant enumerate + +--- + .../android/server/biometrics/BiometricServiceBase.java | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +index 4031cd32829..e74343ce4de 100644 +--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java ++++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +@@ -323,6 +323,7 @@ public abstract class BiometricServiceBase extends SystemService + private List mEnrolledList; + // List of templates to remove from the HAL + private List mUnknownHALTemplates = new ArrayList<>(); ++ final boolean mNocleanup = android.os.SystemProperties.getBoolean("persist.sys.phh.fingerprint.nocleanup", false); + + InternalEnumerateClient(Context context, + DaemonWrapper daemon, long halDeviceId, IBinder token, +@@ -367,9 +368,11 @@ public abstract class BiometricServiceBase extends SystemService + BiometricAuthenticator.Identifier identifier = mEnrolledList.get(i); + Slog.e(getTag(), "doTemplateCleanup(): Removing dangling template from framework: " + + identifier.getBiometricId() + " " +- + identifier.getName()); +- mUtils.removeBiometricForUser(getContext(), +- getTargetUserId(), identifier.getBiometricId()); ++ + identifier.getName() + " /// " + mNocleanup); ++ if(!mNocleanup) { ++ mUtils.removeBiometricForUser(getContext(), ++ getTargetUserId(), identifier.getBiometricId()); ++ } + StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, + statsModality(), + BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_FRAMEWORK); +-- +2.17.1 + diff --git a/patches/platform_frameworks_base/0055-Support-Realme-FOD.patch b/patches/platform_frameworks_base/0055-Support-Realme-FOD.patch new file mode 100644 index 0000000..3e3c0cb --- /dev/null +++ b/patches/platform_frameworks_base/0055-Support-Realme-FOD.patch @@ -0,0 +1,293 @@ +From 612be3c02c49dc81924a58bf503bb04dfaa6b639 Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Tue, 10 Mar 2020 23:32:00 +0100 +Subject: [PATCH 55/55] Support Realme FOD + +List of changes: +- Enable dimlayer_hbm. This dims the framebuffer, while putting screen +into HBM. From user's POV, brightness didn't change, but this enables +HBM facola. +- Have two separate FOD layers +This is needed because hwcomposer is expecting two FOD layers to tell +fingerprint HAL that UI is ready. +Also, using the second magical layer makes this second layer OVER the +dim, so it is running at full brightness. +- All devices are now moved to two layers. +- Sending events to other HALs have been delayed by 200ms, to account +for slow brightness change +--- + services/core/Android.bp | 1 + + .../biometrics/fingerprint/FacolaView.java | 146 ++++++++++++++++-- + 2 files changed, 132 insertions(+), 15 deletions(-) + +diff --git a/services/core/Android.bp b/services/core/Android.bp +index 84a5450dc05..dd0575c0b02 100644 +--- a/services/core/Android.bp ++++ b/services/core/Android.bp +@@ -56,6 +56,7 @@ java_library_static { + "netd_event_listener_interface-java", + "vendor.goodix.extend.service-V2.0-java", + "vendor.samsung.hardware.biometrics.fingerprint-V2.1-java", ++ "vendor.oppo.hardware.biometrics.fingerprint-V2.1-java", + "vendor.xiaomi.hardware.fingerprintextension-V1.0-java", + ], + } +diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FacolaView.java b/services/core/java/com/android/server/biometrics/fingerprint/FacolaView.java +index 2c1ba76f529..42f21d63430 100644 +--- a/services/core/java/com/android/server/biometrics/fingerprint/FacolaView.java ++++ b/services/core/java/com/android/server/biometrics/fingerprint/FacolaView.java +@@ -19,6 +19,7 @@ package com.android.server.biometrics.fingerprint; + import android.graphics.Canvas; + import android.graphics.Color; + import android.graphics.Paint; ++import android.graphics.Point; + import android.content.Context; + import android.view.View.OnTouchListener; + import android.view.View; +@@ -39,19 +40,23 @@ import vendor.xiaomi.hardware.fingerprintextension.V1_0.IXiaomiFingerprint; + import vendor.goodix.extend.service.V2_0.IGoodixFPExtendService; + import vendor.samsung.hardware.biometrics.fingerprint.V2_1.ISecBiometricsFingerprint; + ++import android.hardware.display.DisplayManager; ++ + import android.os.Handler; + import android.os.HandlerThread; + import android.os.ServiceManager; + + public class FacolaView extends ImageView implements OnTouchListener { +- private final int mX, mY, mW, mH; ++ private int mX, mY, mW, mH; + private final Paint mPaintFingerprint = new Paint(); + private final Paint mPaintShow = new Paint(); + private IXiaomiFingerprint mXiaomiFingerprint = null; + private IGoodixFPExtendService mGoodixFingerprint = null; + private ISecBiometricsFingerprint mSamsungFingerprint = null; ++ private vendor.oppo.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint mOppoFingerprint = null; + private boolean mInsideCircle = false; + private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); ++ private final WindowManager.LayoutParams mParamsTouched = new WindowManager.LayoutParams(); + + private final static float UNTOUCHED_DIM = .1f; + private final static float TOUCHED_DIM = .9f; +@@ -60,20 +65,34 @@ public class FacolaView extends ImageView implements OnTouchListener { + private final Handler mHandler; + + private final WindowManager mWM; ++ private final DisplayManager mDM; + private final boolean samsungFod = samsungHasCmd("fod_enable"); +- private final boolean noDim; ++ private boolean noDim; + ++ private boolean mFullGreenDisplayed = false; ++ private final View mFullGreen; + private boolean mHidden = true; + FacolaView(Context context) { + super(context); + ++ mFullGreen = new ImageView(context) { ++ @Override ++ protected void onDraw(Canvas canvas) { ++ super.onDraw(canvas); ++ canvas.drawCircle(mW/2, mH/2, (float) (mW/2.0f), mPaintFingerprint); ++ }; ++ }; ++ ++ mWM = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); ++ mDM = (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE); ++ + android.util.Log.d("PHH", "Samsung FOD " + samsungFod); + + mHandlerThread = new HandlerThread("FacolaThread"); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + +- noDim = android.os.SystemProperties.getBoolean("persist.sys.phh.nodim", false); ++ noDim = android.os.SystemProperties.getBoolean("persist.sys.phh.nodim", true); + String[] location = android.os.SystemProperties.get("persist.vendor.sys.fp.fod.location.X_Y", "").split(","); + if(location.length != 2) + location = android.os.SystemProperties.get("persist.sys.fp.fod.location.X_Y", "").split(","); +@@ -94,13 +113,29 @@ public class FacolaView extends ImageView implements OnTouchListener { + mH = -1; + } + ++ int oppoSize = android.os.SystemProperties.getInt("persist.vendor.fingerprint.optical.iconsize", 0); ++ if(oppoSize > 0) { ++ mW = oppoSize; ++ mH = oppoSize; ++ } ++ int oppoLocation = android.os.SystemProperties.getInt("persist.vendor.fingerprint.optical.iconlocation", 0); ++ if(oppoLocation > 0) { ++ Slog.d("PHH-Enroll", "Got Oppo icon location " + oppoLocation); ++ Point p = new Point(); ++ mDM.getDisplay(0).getRealSize(p); ++ Slog.d("PHH-Enroll", "\tscreen size " + p.x + ", " + p.y); ++ mX = p.x/2 - mW/2; ++ mY = p.y - mH/2 - oppoLocation; ++ Slog.d("PHH-Enroll", "\tfacola at " + mX + ", " + mY); ++ noDim = true; ++ } ++ + mPaintFingerprint.setAntiAlias(true); + mPaintFingerprint.setColor(Color.GREEN); + + mPaintShow.setAntiAlias(true); + mPaintShow.setColor(Color.argb(0x18, 0x00, 0xff, 0x00)); + setOnTouchListener(this); +- mWM = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); + Slog.d("PHH-Enroll", "Created facola..."); + if(mW != -1) { + try { +@@ -118,6 +153,17 @@ public class FacolaView extends ImageView implements OnTouchListener { + } catch(Exception e) { + Slog.d("PHH-Enroll", "Failed getting samsung fingerprint service", e); + } ++ try { ++ mOppoFingerprint = vendor.oppo.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint.getService(); ++ } catch(Exception e) { ++ Slog.d("PHH-Enroll", "Failed getting oppo fingerprint service", e); ++ } ++ } ++ ++ if(mX != -1) { ++ android.os.SystemProperties.set("persist.sys.phh.has_fod", "true"); ++ } else { ++ android.os.SystemProperties.set("persist.sys.phh.has_fod", "false"); + } + } + +@@ -143,21 +189,53 @@ public class FacolaView extends ImageView implements OnTouchListener { + //TODO w!=h? + if(mInsideCircle) { + try { +- int nitValue = 2; +- if(mXiaomiFingerprint != null) { +- mXiaomiFingerprint.extCmd(0xa, nitValue); +- } else if(mGoodixFingerprint != null) { +- mGoodixFingerprint.goodixExtendCommand(10, 1); +- } else if(mSamsungFingerprint != null) { +- mSamsungFingerprint.request(22 /* SEM_FINGER_STATE */, 0, 2 /* pressed */, new java.util.ArrayList(), +- (int retval, java.util.ArrayList out) -> {} ); ++ mParamsTouched.x = mX; ++ mParamsTouched.y = mY; ++ ++ mParamsTouched.height = mW; ++ mParamsTouched.width = mH; ++ mParamsTouched.format = PixelFormat.TRANSLUCENT; ++ ++ mParamsTouched.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; ++ mParamsTouched.setTitle("Fingerprint on display.touched"); ++ mParamsTouched.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | ++ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; ++ mParamsTouched.dimAmount = UNTOUCHED_DIM; ++ if(!noDim) { ++ mParamsTouched.dimAmount = TOUCHED_DIM; ++ mParamsTouched.screenBrightness = 1.0f; + } ++ ++ mParamsTouched.packageName = "android"; ++ ++ mParamsTouched.gravity = Gravity.TOP | Gravity.LEFT; ++ if(!mFullGreenDisplayed && !mHidden) { ++ mHandler.post( () -> { ++ Slog.d("PHH-Enroll", "Adding full green because of finger pressed"); ++ mFullGreenDisplayed = true; ++ mWM.addView(mFullGreen, mParamsTouched); ++ }); ++ } ++ ++ int nitValue = 2; ++ mHandler.postDelayed( () -> { ++ try { ++ if(mXiaomiFingerprint != null) { ++ mXiaomiFingerprint.extCmd(0xa, nitValue); ++ } else if(mGoodixFingerprint != null) { ++ mGoodixFingerprint.goodixExtendCommand(10, 1); ++ } else if(mSamsungFingerprint != null) { ++ mSamsungFingerprint.request(22 /* SEM_FINGER_STATE */, 0, 2 /* pressed */, new java.util.ArrayList(), ++ (int retval, java.util.ArrayList out) -> {} ); ++ } ++ } catch(Exception e) { ++ Slog.d("PHH-Enroll", "Failed calling late fp extcmd", e); ++ } ++ }, 200); + } catch(Exception e) { + Slog.d("PHH-Enroll", "Failed calling fp extcmd", e); + } + oppoPress(true); +- +- canvas.drawCircle(mW/2, mH/2, (float) (mW/2.0f), this.mPaintFingerprint); + } else { + oppoPress(false); + try { +@@ -172,8 +250,15 @@ public class FacolaView extends ImageView implements OnTouchListener { + } catch(Exception e) { + Slog.d("PHH-Enroll", "Failed calling fp extcmd", e); + } +- canvas.drawCircle(mW/2, mH/2, (float) (mW/2.0f), this.mPaintShow); ++ if(mFullGreenDisplayed) { ++ mHandler.post( () -> { ++ Slog.d("PHH-Enroll", "Removing full green because of finger released"); ++ mFullGreenDisplayed = false; ++ mWM.removeView(mFullGreen); ++ }); ++ } + } ++ canvas.drawCircle(mW/2, mH/2, (float) (mW/2.0f), this.mPaintShow); + } + + @Override +@@ -211,7 +296,15 @@ public class FacolaView extends ImageView implements OnTouchListener { + Slog.d("PHH-Enroll", "Show", new Exception()); + if(!mHidden) return; + mHidden = false; ++ if(mOppoFingerprint != null) { ++ try { ++ mOppoFingerprint.setScreenState(vendor.oppo.hardware.biometrics.fingerprint.V2_1.FingerprintScreenState.FINGERPRINT_SCREEN_ON); ++ } catch(Exception e) { ++ Slog.d("PHH-Enroll", "Failed setting oppo screen state", e); ++ } ++ } + mInsideCircle = false; ++ writeFile("/sys/kernel/oppo_display/dimlayer_hbm", "1"); + if(samsungFod) { + samsungCmd("fod_enable,1,1"); + } +@@ -254,7 +347,20 @@ public class FacolaView extends ImageView implements OnTouchListener { + mInsideCircle = false; + Slog.d("PHH-Enroll", "Hide", new Exception()); + if(mHidden) return; ++ if(mOppoFingerprint != null) { ++ try { ++ mOppoFingerprint.setScreenState(vendor.oppo.hardware.biometrics.fingerprint.V2_1.FingerprintScreenState.FINGERPRINT_SCREEN_ON); ++ } catch(Exception e) { ++ Slog.d("PHH-Enroll", "Failed setting oppo screen state", e); ++ } ++ } ++ writeFile("/sys/kernel/oppo_display/dimlayer_hbm", "0"); + mHidden = true; ++ if(mFullGreenDisplayed) { ++ Slog.d("PHH-Enroll", "Removing full green because of hide"); ++ mFullGreenDisplayed = false; ++ mWM.removeView(mFullGreen); ++ } + if(samsungFod) { + samsungCmd("fod_enable,0"); + } +@@ -325,4 +431,14 @@ public class FacolaView extends ImageView implements OnTouchListener { + } + } + ++ private static void writeFile(String path, String value) { ++ try { ++ PrintWriter writer = new PrintWriter(path, "UTF-8"); ++ writer.println(value); ++ writer.close(); ++ } catch(Exception e) { ++ android.util.Log.d("PHH", "Failed writing to " + path + ": " + value); ++ } ++ } ++ + } +-- +2.17.1 + diff --git a/patches/platform_frameworks_native/0007-Use-BKK-s-hwcomposer-hacks-to-properly-display-FOD-l.patch b/patches/platform_frameworks_native/0007-Use-BKK-s-hwcomposer-hacks-to-properly-display-FOD-l.patch new file mode 100644 index 0000000..b55ab0b --- /dev/null +++ b/patches/platform_frameworks_native/0007-Use-BKK-s-hwcomposer-hacks-to-properly-display-FOD-l.patch @@ -0,0 +1,40 @@ +From c982ade7da4d434e0a779b003e6bfcc6141232b6 Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Tue, 10 Mar 2020 23:26:55 +0100 +Subject: [PATCH 7/7] Use BKK's hwcomposer hacks to properly display FOD layers + +Insecure hack: Set FOD layers to magical Z values to trigger +OPPO/Realme/Oneplus' whole blitter behaviours: +- reports touch event to fingerprint driver +- removes dim on touched layer +--- + .../CompositionEngine/src/OutputLayer.cpp | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +index 5ce72b087..23b29d6fd 100644 +--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp ++++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +@@ -335,7 +335,18 @@ void OutputLayer::writeStateToHWC(bool includeGeometry) const { + static_cast(error)); + } + +- if (auto error = hwcLayer->setZOrder(mState.z); error != HWC2::Error::None) { ++ int z = mState.z; ++ if(strstr(mLayerFE->getDebugName(), "Fingerprint on display") != nullptr) { ++ ALOGE("Found fingerprint on display!"); ++ z = 0x41000031; ++ } ++ ++ if(strstr(mLayerFE->getDebugName(), "Fingerprint on display.touched") != nullptr) { ++ ALOGE("Found fingerprint on display touched!"); ++ z = 0x41000033; ++ } ++ ++ if (auto error = hwcLayer->setZOrder(z); error != HWC2::Error::None) { + ALOGE("[%s] Failed to set Z %u: %s (%d)", mLayerFE->getDebugName(), mState.z, + to_string(error).c_str(), static_cast(error)); + } +-- +2.17.1 + diff --git a/patches/platform_system_vold/0006-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch.bak b/patches/platform_system_vold/0006-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch.bak deleted file mode 100644 index b6fad66..0000000 --- a/patches/platform_system_vold/0006-Check-needsCheckpoint-only-if-checkpoint-is-supporte.patch.bak +++ /dev/null @@ -1,32 +0,0 @@ -From d184ff43ee1dd74f64fd9a0db99c29a225c22147 Mon Sep 17 00:00:00 2001 -From: Pierre-Hugues Husson -Date: Mon, 16 Sep 2019 13:49:05 +0200 -Subject: [PATCH 6/6] Check needsCheckpoint only if checkpoint is supported - -This is needed because some devices (Xiaomi MiPad 4, uncertified) -declares a bootctrl HAL in manifest, but doesn't have it. -vold will then hang in needsCheckpoint waiting for bootctrl - -Change-Id: I2dafcbca7e994d7a3ac36ef3698590db2ab482fa ---- - cryptfs.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/cryptfs.cpp b/cryptfs.cpp -index 07617e9..dbdc5af 100644 ---- a/cryptfs.cpp -+++ b/cryptfs.cpp -@@ -1643,7 +1643,9 @@ static int cryptfs_restart_internal(int restart_main) { - SLOGE("Failed to setexeccon"); - return -1; - } -- bool needs_cp = android::vold::cp_needsCheckpoint(); -+ bool supportsCheckpoint = false; -+ android::vold::cp_supportsCheckpoint(supportsCheckpoint); -+ bool needs_cp = supportsCheckpoint && android::vold::cp_needsCheckpoint(); - while ((mount_rc = fs_mgr_do_mount(&fstab_default, DATA_MNT_POINT, crypto_blkdev, 0, - needs_cp)) != 0) { - if (mount_rc == FS_MGR_DOMNT_BUSY) { --- -2.17.1 - diff --git a/patches/platform_system_vold/0008-Failing-to-create-facedata-shouldn-t-be-fatal.patch b/patches/platform_system_vold/0008-Failing-to-create-facedata-shouldn-t-be-fatal.patch new file mode 100644 index 0000000..e2cd65a --- /dev/null +++ b/patches/platform_system_vold/0008-Failing-to-create-facedata-shouldn-t-be-fatal.patch @@ -0,0 +1,38 @@ +From e4a3ff285cb25559117d38d573e79a6fc34cc9f5 Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Sat, 7 Mar 2020 14:49:09 +0100 +Subject: [PATCH 8/9] Failing to create facedata shouldn't be fatal + +Some Pie vendors create it on their own, so SELinux would deny that +Also not all devices have face unlock anyway + +See https://github.com/phhusson/treble_experimentations/issues/1119 +--- + vold_prepare_subdirs.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp +index a620edd..e07528f 100644 +--- a/vold_prepare_subdirs.cpp ++++ b/vold_prepare_subdirs.cpp +@@ -136,7 +136,7 @@ static bool prepare_subdirs(const std::string& volume_uuid, int user_id, int fla + } + auto facedata_path = vendor_de_path + "/facedata"; + if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, facedata_path)) { +- return false; ++ LOG(ERROR) << "Failed preparing folder for de facedata"; + } + } + if (flags & android::os::IVold::STORAGE_FLAG_CE) { +@@ -156,7 +156,7 @@ static bool prepare_subdirs(const std::string& volume_uuid, int user_id, int fla + auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id); + auto facedata_path = vendor_ce_path + "/facedata"; + if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, facedata_path)) { +- return false; ++ LOG(ERROR) << "Failed preparing folder for de facedata"; + } + } + } +-- +2.17.1 + diff --git a/patches/platform_system_vold/0009-Every-voldmanaged-storage-is-adoptable.patch b/patches/platform_system_vold/0009-Every-voldmanaged-storage-is-adoptable.patch new file mode 100644 index 0000000..09e9b77 --- /dev/null +++ b/patches/platform_system_vold/0009-Every-voldmanaged-storage-is-adoptable.patch @@ -0,0 +1,25 @@ +From 110923dbe0191b030e1ee6f25f3109de78a8f876 Mon Sep 17 00:00:00 2001 +From: Pierre-Hugues Husson +Date: Wed, 11 Mar 2020 14:02:35 +0100 +Subject: [PATCH 9/9] Every voldmanaged storage is adoptable + +--- + main.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/main.cpp b/main.cpp +index 27a701b..cd1d6dd 100644 +--- a/main.cpp ++++ b/main.cpp +@@ -249,7 +249,7 @@ static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quot + std::string nickname(entry.label); + int flags = 0; + +- if (entry.is_encryptable()) { ++ if (entry.is_encryptable() || true) { + flags |= android::vold::Disk::Flags::kAdoptable; + *has_adoptable = true; + } +-- +2.17.1 +