This document describes the required SystemUI, framework, and vendor modifications to restore Fingerprint-on-Display (FOD) functionality on HyperOS for Transsion devices using non-AIDL fingerprint stacks.
The procedure consists of:
- Patching
SystemUI.apk - Adding a custom receiver for FOD HBM Layer handling
- Patching vendor binaries
- Forcing fingerprint hardware detection if the UI option is missing
com.miui.keyguard.biometrics.fod.MiuiGxzwIconView
At the top of the class, add:
.field public mRianixiaReceiver:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
Completely replace the method with the following implementation:
.method public final dismissGxzwIconView(Z)V
.registers 6
sget-boolean v0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwUtils;->GXZW_LOWLIGHT_SENSOR:Z
if-eqz v0, :cond_1b
invoke-virtual {p0}, Landroid/widget/FrameLayout;->getContext()Landroid/content/Context;
sget-boolean v0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwUtils;->SUPPORT_NO_TOUCH_MODE:Z
if-nez v0, :cond_1b
const-class v0, Lcom/miui/systemui/MiuiUiOffloadThread;
invoke-static {v0}, Lcom/miui/systemui/MiuiDependency;->get(Ljava/lang/Class;)Ljava/lang/Object;
move-result-object v0
check-cast v0, Lcom/miui/systemui/MiuiUiOffloadThread;
new-instance v1, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$$ExternalSyntheticLambda1;
invoke-direct {v1, p1}, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$$ExternalSyntheticLambda1;-><init>(Z)V
invoke-virtual {v0, v1}, Lcom/miui/systemui/MiuiUiOffloadThread;->execute(Ljava/lang/Runnable;)V
:cond_1b
const/4 v0, 0x0
const/16 v1, 0x8
iget-object v3, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mRianixiaReceiver:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
if-eqz v3, :cond_25
invoke-virtual {v3}, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;->removeHbmOverlay()V
:cond_25
if-eqz p1, :cond_29
move v2, v1
goto :goto_2a
:cond_29
move v2, v0
:goto_2a
invoke-virtual {p0, v2}, Landroid/widget/FrameLayout;->setVisibility(I)V
iget-object v2, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mHighlightView:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwHightlightContainer;
if-eqz v2, :cond_39
if-eqz p1, :cond_35
move v3, v1
goto :goto_36
:cond_35
move v3, v0
:goto_36
invoke-virtual {v2, v3}, Landroid/widget/FrameLayout;->setVisibility(I)V
:cond_39
iget-object v2, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mMiuiGxzwAnimView:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView;
if-eqz p1, :cond_3e
move v0, v1
:cond_3e
iget-object p1, v2, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView;->mMainHandler:Landroid/os/Handler;
new-instance v1, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView$$ExternalSyntheticLambda16;
invoke-direct {v1, v2, v0}, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView$$ExternalSyntheticLambda16;-><init>(Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView;I)V
invoke-virtual {p1, v1}, Landroid/os/Handler;->post(Ljava/lang/Runnable;)Z
iget-object p0, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mMiuiGxzwAnimView:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView;
iget-object p1, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView;->mMainHandler:Landroid/os/Handler;
new-instance v0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView$$ExternalSyntheticLambda0;
const/4 v1, 0x7
invoke-direct {v0, p0, v1}, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView$$ExternalSyntheticLambda0;-><init>(Lcom/miui/keyguard/biometrics/fod/MiuiGxzwAnimView;I)V
invoke-virtual {p1, v0}, Landroid/os/Handler;->post(Ljava/lang/Runnable;)Z
return-void
.end method.method public final onAttachedToWindow()V
.registers 4
invoke-super {p0}, Lcom/miui/keyguard/biometrics/fod/GxzwWindowFrameLayout;->onAttachedToWindow()V
invoke-virtual {p0, p0}, Landroid/widget/FrameLayout;->setOnTouchListener(Landroid/view/View$OnTouchListener;)V
new-instance v0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
invoke-direct {v0, p0}, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;-><init>(Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;)V
iput-object v0, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mRianixiaReceiver:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
new-instance v1, Landroid/content/IntentFilter;
invoke-direct {v1}, Landroid/content/IntentFilter;-><init>()V
const-string v2, "com.rianixia.FINGER_DOWN"
invoke-virtual {v1, v2}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V
const-string v2, "com.rianixia.FINGER_UP"
invoke-virtual {v1, v2}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V
invoke-virtual {p0}, Landroid/widget/FrameLayout;->getContext()Landroid/content/Context;
move-result-object v2
iget-object v0, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mRianixiaReceiver:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
invoke-virtual {v2, v0, v1}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;
return-void
.end method.method public final onDetachedFromWindow()V
.registers 3
invoke-super {p0}, Lcom/miui/keyguard/biometrics/fod/GxzwWindowFrameLayout;->onDetachedFromWindow()V
const/4 v0, 0x0
invoke-virtual {p0, v0}, Landroid/widget/FrameLayout;->setOnTouchListener(Landroid/view/View$OnTouchListener;)V
iget-object v0, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mRianixiaReceiver:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
if-eqz v0, :cond_18
invoke-virtual {v0}, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;->removeHbmOverlay()V
invoke-virtual {p0}, Landroid/widget/FrameLayout;->getContext()Landroid/content/Context;
move-result-object v1
invoke-virtual {v1, v0}, Landroid/content/Context;->unregisterReceiver(Landroid/content/BroadcastReceiver;)V
const/4 v0, 0x0
iput-object v0, p0, Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView;->mRianixiaReceiver:Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
:cond_18
return-void
.end methodAdd the following class to SystemUI:
Lcom/miui/keyguard/biometrics/fod/MiuiGxzwIconView$RianixiaReceiver;
- Copy the provided vendor blobs
- Patch SELinux context to
fingerprint_default_exec - Ensure the service executes correctly under vendor partition
If the fingerprint option does not appear:
- Run in permissive mode or
- Patch
services.jar
com.android.server.biometrics.sensors.fingerprint.FingerprintService$1
.method public isHardwareDetected(ILjava/lang/String;)Z
.registers 8
const/4 v1, 0x1
return v1
.end method
.method public isHardwareDetectedDeprecated(Ljava/lang/String;Ljava/lang/String;)Z
.registers 10
const/4 v1, 0x1
return v1
.end method- Import Transsion AOSP FOD HALs. (Provided in the Repo)
- Patch
hwcomposer.*under/vendor/lib64/hw/.
Example:
perl -pi -e 's/OnScreenFingerprintDimLayer/VRI[RianixiaHBMController]\x00/g' /vendor/lib64/hw/hwcomposer.mt6893.so- Fod Props
persist.vendor.sys.fp.fod.location.X_Y=380,2018
persist.vendor.sys.fp.fod.size.width_height=320,320
ro.hardware.fp.fod=true
ro.hardware.fp.fod.location=low
ro.hardware.fp.fod.touch.ctl.version=2.0
ro.vendor.display.fod_monitor_default_fps=120
ro.optical_fingerprint_support=1
persist.vendor.fingerprint.sensor_modules=goodix
persist.vendor.fingerprint.sensor_type=optical
persist.vendor.fingerprint.type=optical
- Tested with Goodix FOD only
- Other fingerprint types are unverified
- Tested in HyperOS 2
- Might need slight changes for HyperOS 1 or 3
- irawansalt & fajarxtr — Transsion AOSP FOD HALs
- @ryanistr (GitHub) / @rianixia (Telegram) — HyperOS FOD implementation