Android11添加AIDL系统服务及HIDL接口服务
创始人
2024-04-28 18:17:50
0

软件平台:Android11

硬件平台:QCS6125

    直接上需求:首先添加自定义系统服务并且开机自启动;其次该服务要调用HW层service的方法。

    前半部分之前添加过N次,不是难点,后半部分的实现最开始也是想借助binder通信,直接去调用接口,遇到了一大堆selinux权限问题,这是google针对android8.0之后新添加的策略,使用了三个binder,分别是标准/dev/binder该节点主要用于System分区的系统服务去注册使用,/dev/hwbinder该节点主要用于运行于HW的服务注册使用,/dev/vndbinder该节点主要用于运行在vendor分区的服务注册使用,而需求中所说的HW层的服务注册的是vndbinder,自定义的服务是binder,因此系统层面是隔离的,无法通过binder直接通信,只能通过hwbinder去迂回,因为binder可以跟hwbinder通信,而hwbinder可以和vndbinder交互,从而达到binder服务和vndbinder服务通信的目的。

前半部分(系统服务)的实现:

1、创建frameworks/base/core/java/android/app/yfd/目录,建立如下文件:

HandWriteManager.java

/************************************************************************** File Name: HandWriteManager.java* Author: kongbo * Mail: shenyoutianji@126.com * Created Time: 2022年11月21日 星期一 17时17分35秒************************************************************************/
package android.app.yfd;import android.content.Context;import android.os.RemoteException;import android.util.Slog;public class HandWriteManager {Context mContext;IHandWriteManager mService;static final String TAG = "HandWriteManager";public HandWriteManager(Context context, IHandWriteManager service) {mContext = context;mService = service;if (mService != null)Slog.d(TAG, " mService not null");}public void setRefreshMode(int mode) {if (mService != null) {Slog.d(TAG, " Will setRefreshMode");try {mService.setRefreshMode(mode);} catch (RemoteException e) {Slog.d(TAG, "RemoteException " + e);}}//return null;}public void commitRefreshArea(int x, int y, int h, int w) {if (mService != null) {Slog.d(TAG, " Will commitRefreshArea");try {mService.commitRefreshArea(x, y, h, w);} catch (RemoteException e) {Slog.d(TAG, "RemoteException " + e);}}}}

IHandWriteManager.aidl

/*** Hand Writes Service*/package android.app.yfd;interface IHandWriteManager {void setRefreshMode(int mode);void commitRefreshArea(int x, int y, int h, int w);}

frameworks/base/services/core/java/com/android/server目录添加HandWriteManagerService.java

/************************************************************************** File Name: HandWriteManagerService.java* Author: kongbo* Mail:nubility@gmail.com * Created Time: 2022年11月21日 星期一 17时36分04秒************************************************************************/
package com.android.server;import android.app.yfd.IHandWriteManager;import android.content.Context;import android.os.Build;import android.util.Slog;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.FileReader;import java.io.IOException;public class HandWriteManagerService extends IHandWriteManager.Stub {private Context mContext;static final String TAG = "HandWriteManagerService";private boolean Debug = true;private final int LEISURE_MODE = 1;private final int WRITE_MODE = 2;private final int NETWORK_MODE = 3;private native void HandWriteServiceNative_setRefreshMode(int mode);private native void HandWriteServiceNative_Init();private native void HandWriteServiceNative_commitRefreshArea(int x, int y, int h, int w);public HandWriteManagerService(Context context) {//Slog.e(TAG," ====== call native method HandWriteServiceNative_Init");HandWriteServiceNative_Init();mContext = context;/*try {Slog.e(TAG," ====== Runtime will exec ======");Runtime.getRuntime().exec("su");Runtime.getRuntime().exec("vndservice call display.qservice 47 i32 2");Slog.e(TAG," ====== Runtime exec end ======");} catch (IOException e) {Slog.e(TAG," ====== Runtime exec has exception ======");e.printStackTrace();}*/}@Overridepublic void setRefreshMode(int mode) {BufferedWriter bufWriter = null;try {//bufWriter = new BufferedWriter(new FileWriter(LMAP_BRIGHTNESS_PATH));if (Debug)Slog.e(TAG," ====== write brightness:");HandWriteServiceNative_setRefreshMode(mode);//bufWriter.write(String.valueOf(brightness));//bufWriter.close();} catch (Exception e) {e.printStackTrace();}}@Overridepublic void commitRefreshArea(int x, int y, int h, int w) {HandWriteServiceNative_commitRefreshArea(x, y, h, w);}
}

向SystemServer完成注册:

diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index e599a5ce81e..38473ee5e6e 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -43,6 +43,8 @@ import android.app.usage.IUsageStatsManager;import android.app.usage.NetworkStatsManager;import android.app.usage.StorageStatsManager;import android.app.usage.UsageStatsManager;
+import android.app.yfd.HandWriteManager;
+import android.app.yfd.IHandWriteManager;import android.appwidget.AppWidgetManager;import android.bluetooth.BluetoothManager;import android.companion.CompanionDeviceManager;
@@ -1189,6 +1191,17 @@ public final class SystemServiceRegistry {}});+        registerService(Context.HAND_WRITE_SERVICE, HandWriteManager.class,
+                new CachedServiceFetcher() {
+                    @Override
+                    public HandWriteManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder b = ServiceManager.getServiceOrThrow(
+                                Context.HAND_WRITE_SERVICE);
+                        return new HandWriteManager(ctx, IHandWriteManager.Stub.asInterface(b));
+                    }
+                });
+registerService(Context.SLICE_SERVICE, SliceManager.class,new CachedServiceFetcher() {@Override
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index e599a5ce81e..38473ee5e6e 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -43,6 +43,8 @@ import android.app.usage.IUsageStatsManager;import android.app.usage.NetworkStatsManager;import android.app.usage.StorageStatsManager;import android.app.usage.UsageStatsManager;
+import android.app.yfd.HandWriteManager;
+import android.app.yfd.IHandWriteManager;import android.appwidget.AppWidgetManager;import android.bluetooth.BluetoothManager;import android.companion.CompanionDeviceManager;
@@ -1189,6 +1191,17 @@ public final class SystemServiceRegistry {}});+        registerService(Context.HAND_WRITE_SERVICE, HandWriteManager.class,
+                new CachedServiceFetcher() {
+                    @Override
+                    public HandWriteManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder b = ServiceManager.getServiceOrThrow(
+                                Context.HAND_WRITE_SERVICE);
+                        return new HandWriteManager(ctx, IHandWriteManager.Stub.asInterface(b));
+                    }
+                });
+registerService(Context.SLICE_SERVICE, SliceManager.class,new CachedServiceFetcher() {@Override

在Context.java添加服务ID定义:

diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8472144a92c..d9ee340cd55 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5024,6 +5024,15 @@ public abstract class Context {*/public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.app.yfd.HandWriteManager} for handwriting
+     *
+     * @see #getSystemService(String)
+     * @see android.app.yfd.HandWriteManager
+     */
+    public static final String HAND_WRITE_SERVICE  = "hand_write";
+/*** Use with {@link #getSystemService} to retrieve a* {@link android.se.omapi.ISecureElementService}

此时增量编译代码,会提示api需要更新还有一个lint检测的报错,API更新执行make update-api指令,去掉lint检查需要修改framework/base/Android.bp如下:

diff --git a/Android.bp b/Android.bp
index bf6c99d0cf2..bb4a6a9a4e7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1219,7 +1219,8 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x"--api-lint-ignore-prefix android.icu. " +"--api-lint-ignore-prefix java. " +"--api-lint-ignore-prefix junit. " +
-    "--api-lint-ignore-prefix org. "
+    "--api-lint-ignore-prefix org. " +
+    "--api-lint-ignore-prefix android.app.yfd. "build = ["StubLibraries.bp",

在执行完make update-api之后,系统会自动更新api文件:

diff --git a/api/current.txt b/api/current.txt
index 952ccdad992..f91544dde68 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8106,6 +8106,37 @@ package android.app.usage {}+package android.app.yfd {
+
+  public class HandWriteManager {
+    ctor public HandWriteManager(android.content.Context, android.app.yfd.IHandWriteManager);
+    method public void commitRefreshArea(int, int, int, int);
+    method public void setRefreshMode(int);
+  }
+
+  public interface IHandWriteManager extends android.os.IInterface {
+    method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+    method public void setRefreshMode(int) throws android.os.RemoteException;
+  }
+
+  public static class IHandWriteManager.Default implements android.app.yfd.IHandWriteManager {
+    ctor public IHandWriteManager.Default();
+    method public android.os.IBinder asBinder();
+    method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+    method public void setRefreshMode(int) throws android.os.RemoteException;
+  }
+
+  public abstract static class IHandWriteManager.Stub extends android.os.Binder implements android.app.yfd.IHandWriteManager {
+    ctor public IHandWriteManager.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.app.yfd.IHandWriteManager asInterface(android.os.IBinder);
+    method public static android.app.yfd.IHandWriteManager getDefaultImpl();
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public static boolean setDefaultImpl(android.app.yfd.IHandWriteManager);
+  }
+
+}
+package android.appwidget {public class AppWidgetHost {
@@ -10190,6 +10221,7 @@ package android.content {field public static final String EUICC_SERVICE = "euicc";field public static final String FILE_INTEGRITY_SERVICE = "file_integrity";field public static final String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final String HAND_WRITE_SERVICE = "hand_write";field public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";field public static final String INPUT_METHOD_SERVICE = "input_method";field public static final String INPUT_SERVICE = "input";
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 5f15216e840..c6047ab6ff4 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -8106,6 +8106,37 @@ package android.app.usage {}+package android.app.yfd {
+
+  public class HandWriteManager {
+    ctor public HandWriteManager(android.content.Context, android.app.yfd.IHandWriteManager);
+    method public void commitRefreshArea(int, int, int, int);
+    method public void setRefreshMode(int);
+  }
+
+  public interface IHandWriteManager extends android.os.IInterface {
+    method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+    method public void setRefreshMode(int) throws android.os.RemoteException;
+  }
+
+  public static class IHandWriteManager.Default implements android.app.yfd.IHandWriteManager {
+    ctor public IHandWriteManager.Default();
+    method public android.os.IBinder asBinder();
+    method public void commitRefreshArea(int, int, int, int) throws android.os.RemoteException;
+    method public void setRefreshMode(int) throws android.os.RemoteException;
+  }
+
+  public abstract static class IHandWriteManager.Stub extends android.os.Binder implements android.app.yfd.IHandWriteManager {
+    ctor public IHandWriteManager.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.app.yfd.IHandWriteManager asInterface(android.os.IBinder);
+    method public static android.app.yfd.IHandWriteManager getDefaultImpl();
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public static boolean setDefaultImpl(android.app.yfd.IHandWriteManager);
+  }
+
+}
+package android.appwidget {public class AppWidgetHost {
@@ -10190,6 +10221,7 @@ package android.content {field public static final String EUICC_SERVICE = "euicc";field public static final String FILE_INTEGRITY_SERVICE = "file_integrity";field public static final String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final String HAND_WRITE_SERVICE = "hand_write";field public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";field public static final String INPUT_METHOD_SERVICE = "input_method";field public static final String INPUT_SERVICE = "input";

接着添加服务的jni层:

frameworks/base/services/core/jni添加com_android_server_HandWriteManagerService.cpp

/*************************************************************************> File Name: com_android_server_HandWriteManagerService.cpp> Author: kongbo> Mail: kaka@gmail.com > Created Time: 2022年11月23日 星期三 14时56分34秒************************************************************************/#define LOG_TAG "HandWrite_JNI"
#include "jni.h"
#include "core_jni_helpers.h"
#include 
#include                                                                                                                                       
#include 
#include #include #include 
#include 
#include #include namespace android {/*		
struct hello_device* hello_device = NULL;static inline int hello_device_open(const hw_module_t* module, struct hello_device** device) {return module->methods->open(module, HELLO_HARDWARE_MODULE_ID, (struct hw_device_t**)device);}*/static sp service;static String16 ifName; static String16 get_interface_name(sp service) {if (service != nullptr) {Parcel data, reply;status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);if (err == NO_ERROR) {return reply.readString16();}}return String16();
}static void HandWriteServiceNative_Init(JNIEnv* env, jobject) {
/*	ALOGE("com_android_server_HelloService HelloServiceInit");const hw_module_t *hw_module = NULL;ALOGE("Hello JNI: initializing......");if(hw_get_module(HELLO_HARDWARE_MODULE_ID, &hw_module) == 0) {ALOGE("Hello JNI: hello Stub found.");if(hello_device_open(hw_module, &hello_device) == 0) {ALOGE("Hello JNI: hello device is open.");return 0;}ALOGE("Hello JNI: failed to open hello device.");return -1;}ALOGE("Hello JNI: failed to get hello stub hw_module.");
*/ALOGE("====== HandWriteServiceNative_Init JNI: initializing......");ALOGE("====== HandWriteServiceNative_Init JNI: 000000......");sp sm = defaultServiceManager();ALOGE("====== HandWriteServiceNative_Init JNI: 111111......");service = sm->checkService(String16("SurfaceFlinger"));ALOGE("====== HandWriteServiceNative_Init JNI: 222222......");ifName = get_interface_name(service); ALOGE("====== HandWriteServiceNative_Init JNI: 333333......");if (service != nullptr && ifName.size() > 0) {Parcel data1, data2, reply;ALOGE("====== HandWriteServiceNative_Init JNI: data init");// the interface name is firstdata1.writeInterfaceToken(ifName); int32_t code = atoi("20006");data1.writeInt32(atoi("2"));ALOGE("====== HandWriteServiceNative_Init JNI: 6666666......");service->transact(code, data1, &reply);data2.writeInterfaceToken(ifName); int32_t code1 = atoi("20007");data2.writeInt32(atoi("100"));data2.writeInt32(atoi("100"));data2.writeInt32(atoi("100"));data2.writeInt32(atoi("100"));ALOGE("====== HandWriteServiceNative_Init JNI: 77777777......");service->transact(code1, data2, &reply);}//Runtime.getRuntime().exec("vndservice call display.qservice 47 i32 2");/*bool supported = SurfaceComposerClient::getProtectedContentSupport();if (supported) {ALOGE("====== HandWriteServiceNative_Init getProtectedContentSupport: true");} else {ALOGE("====== HandWriteServiceNative_Init getProtectedContentSupport: false");}*/ALOGE("====== HandWriteServiceNative_Init already write cmd to hwc service");
}static void HandWriteServiceNative_setRefreshMode(JNIEnv* env, jobject clazz, jint nativeValue) {
/*	ALOGE("com_android_server_HelloService HelloServiceNativeSetVal");if(!hello_device) {ALOGI("Hello JNI: hello_device is not open.");return;}const char* local_value = (nativeValue) ? env->GetStringUTFChars(nativeValue, NULL) : NULL;ALOGE("com_android_server_HelloService HelloServiceNativeSetVal local_value = %s",local_value);hello_device->write_string(hello_device, local_value);ALOGI("Hello JNI: write string %s to Hello hello_device.", local_value);env->ReleaseStringUTFChars(nativeValue, local_value);
*/if (service != nullptr && ifName.size() > 0) {Parcel data, reply;// the interface name is firstdata.writeInterfaceToken(ifName); int32_t code = atoi("20006");data.writeInt32(atoi("2"));ALOGE("====== HandWriteServiceNative_Init JNI: 6666666......");service->transact(code, data, &reply);}}static void HandWriteServiceNative_commitRefreshArea(JNIEnv* env, jobject clazz, jint x, jint y, jint h, jint w) {if (service != nullptr && ifName.size() > 0) {Parcel data, reply;// the interface name is firstdata.writeInterfaceToken(ifName); ALOGE("====== HandWriteServiceNative_Init JNI: 6666666......");int32_t code = atoi("20007");data.writeInt32(atoi("100"));data.writeInt32(atoi("100"));data.writeInt32(atoi("100"));data.writeInt32(atoi("100"));service->transact(code, data, &reply);}}
static const JNINativeMethod methods[] = {
//    {"HelloServiceInit", "()I", (void*) HelloServiceInit},{"HandWriteServiceNative_Init", "()V",(void*) HandWriteServiceNative_Init},{"HandWriteServiceNative_setRefreshMode", "(I)V",(void*) HandWriteServiceNative_setRefreshMode},{"HandWriteServiceNative_commitRefreshArea", "(IIII)V",(void*) HandWriteServiceNative_commitRefreshArea},
};int register_android_server_HandWriteService(JNIEnv *env) {return jniRegisterNativeMethods(env, "com/android/server/HandWriteManagerService", methods, NELEM(methods));
}}

将该文件添加到jni的makefile:

diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 88fa8f7d597..72d5eaf8e18 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -60,6 +60,7 @@ cc_library_static {"com_android_server_am_LowMemDetector.cpp","com_android_server_pm_PackageManagerShellCommandDataLoader.cpp","com_android_server_activityTriggerService.cpp",
+        "com_android_server_HandWriteManagerService.cpp","onload.cpp",":lib_networkStatsFactory_native",],

在onload类添加jni method注册:

diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index ec104ec8666..5b5855bffe9 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -53,6 +53,7 @@ int register_android_server_SyntheticPasswordManager(JNIEnv* env);int register_android_hardware_display_DisplayViewport(JNIEnv* env);int register_android_server_net_NetworkStatsFactory(JNIEnv* env);int register_android_server_net_NetworkStatsService(JNIEnv* env);
+int register_android_server_HandWriteService(JNIEnv *env);int register_android_server_security_VerityUtils(JNIEnv* env);int register_android_server_am_CachedAppOptimizer(JNIEnv* env);int register_android_server_am_LowMemDetector(JNIEnv* env);
@@ -111,6 +112,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)register_android_hardware_display_DisplayViewport(env);register_android_server_net_NetworkStatsFactory(env);register_android_server_net_NetworkStatsService(env);
+    register_android_server_HandWriteService(env);register_android_server_security_VerityUtils(env);register_android_server_am_CachedAppOptimizer(env);register_android_server_am_LowMemDetector(env);

至此,前半部分需求开发完成~~~

下面展开第二部分需求:

    因为需求部分是想调用display相关的服务,很容易联想到Framework层的SF是跟显示系统的HW打交道的,而自定义的服务是可以直接跟SF交互的,因此就打算给SF扩展接口来实现,具体改动如下,集中在framework/native目录:

diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index e62a61fc5..a1edb0f78 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -540,6 +540,71 @@ public:return reply.readBool(outSupport);}+    virtual void setPanelRefreshMode(const sp& display, int32_t mode) {
+        Parcel data, reply;
+        status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (result != NO_ERROR) {
+            ALOGE("setPanelRefreshMode failed to writeInterfaceToken: %d", result);
+            return;
+        }
+
+        result = data.writeStrongBinder(display);
+        if (result != NO_ERROR) {
+            ALOGE("setPanelRefreshMode failed to writeStrongBinder: %d", result);
+            return;
+        }
+        result = data.writeInt32(mode);
+        if (result != NO_ERROR) {
+            ALOGE("setPanelRefreshMode failed to writeInt32: %d", result);
+            return;
+        }
+        result = remote()->transact(BnSurfaceComposer::SET_PANEL_REFRESH_MODE, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("setPanelRefreshMode failed to transact: %d", result);
+            return;
+        }
+    }
+
+    virtual void commitRefreshArea(const sp& display, int32_t x, int32_t y, int32_t h, int32_t w) {
+        Parcel data, reply;
+        status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to writeInterfaceToken: %d", result);
+            return;
+        }
+
+        result = data.writeStrongBinder(display);
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to writeStrongBinder: %d", result);
+            return;
+        }
+        result = data.writeInt32(x);
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to writeInt32: %d", result);
+            return;
+        }
+        result = data.writeInt32(y);
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to writeInt32: %d", result);
+            return;
+        }
+        result = data.writeInt32(h);
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to writeInt32: %d", result);
+            return;
+        }
+        result = data.writeInt32(w);
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to writeInt32: %d", result);
+            return;
+        }
+        result = remote()->transact(BnSurfaceComposer::COMMIT_REFRESH_AREA, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("commitRefreshArea failed to transact: %d", result);
+            return;
+        }
+    }
+virtual void setAutoLowLatencyMode(const sp& display, bool on) {Parcel data, reply;status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -1568,6 +1633,57 @@ status_t BnSurfaceComposer::onTransact(return result;}+        case SET_PANEL_REFRESH_MODE: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp display = nullptr;
+            status_t result = data.readStrongBinder(&display);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readStrongBinder: %d", result);
+                return result;
+            }
+            int32_t setAllm = false;
+            result = data.readInt32(&setAllm);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readBool: %d", result);
+                return result;
+            }
+            setPanelRefreshMode(display, setAllm);
+            return result;
+        }
+
+        case COMMIT_REFRESH_AREA: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp display = nullptr;
+            status_t result = data.readStrongBinder(&display);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readStrongBinder: %d", result);
+                return result;
+            }
+            int32_t x, y ,h, w = 0;
+            result = data.readInt32(&x);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readBool: %d", result);
+                return result;
+            }
+            result = data.readInt32(&y);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readBool: %d", result);
+                return result;
+            }
+            result = data.readInt32(&h);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readBool: %d", result);
+                return result;
+            }
+            result = data.readInt32(&w);
+            if (result != NO_ERROR) {
+                ALOGE("setPanelRefreshMode failed to readBool: %d", result);
+                return result;
+            }
+            commitRefreshArea(display, x, y, h, w);
+            return result;
+        }
+case SET_AUTO_LOW_LATENCY_MODE: {CHECK_INTERFACE(ISurfaceComposer, data, reply);sp display = nullptr;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 83bc06997..3dd441e7c 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1792,6 +1792,14 @@ bool SurfaceComposerClient::getAutoLowLatencyModeSupport(const sp& dispreturn supported;}+void SurfaceComposerClient::setPanelRefreshMode(const sp& display, int32_t mode) {
+    ComposerService::getComposerService()->setPanelRefreshMode(display, mode);
+}
+
+void SurfaceComposerClient::commitRefreshArea(const sp& display, int32_t x, int32_t y, int32_t h, int32_t w) {
+    ComposerService::getComposerService()->commitRefreshArea(display, x, y, h, w);
+}
+void SurfaceComposerClient::setAutoLowLatencyMode(const sp& display, bool on) {ComposerService::getComposerService()->setAutoLowLatencyMode(display, on);}
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 8d3160a81..913e334bc 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -228,6 +228,10 @@ public:*/virtual void setAutoLowLatencyMode(const sp& display, bool on) = 0;+    virtual void setPanelRefreshMode(const sp& displayToken, int32_t mode) = 0;
+
+    virtual void commitRefreshArea(const sp& displayToken, int32_t x, int32_t y, int32_t h, int32_t w) = 0;
+/*** Returns true if the connected display reports support for Game Content Type.* For more information, see the HDMI 1.4 specification.
@@ -599,6 +603,8 @@ public:SET_GAME_CONTENT_TYPE,SET_FRAME_RATE,ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN,
+        SET_PANEL_REFRESH_MODE,
+        COMMIT_REFRESH_AREA,// Always append new enum to the end.};diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index adcb8982a..89f1c3540 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -155,6 +155,10 @@ public:// #getAutoLowLatencyModeSupportstatic void setAutoLowLatencyMode(const sp& display, bool on);+    static void setPanelRefreshMode(const sp& displayToken, int32_t mode);
+
+    static void commitRefreshArea(const sp& displayToken, int32_t x, int32_t y, int32_t h, int32_t w);
+// Reports whether the connected display supports Game content typestatic bool getGameContentTypeSupport(const sp& display);diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 805050de2..9990ee385 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -1366,6 +1366,24 @@ V2_4::Error Composer::setAutoLowLatencyMode(Display display, bool on) {return mClient_2_4->setAutoLowLatencyMode(display, on);}+V2_4::Error Composer::setPanelRefreshMode(Display display, int32_t mode) {
+    using Error = V2_4::Error;
+    if (!mClient_2_4) {
+        return Error::UNSUPPORTED;
+    }
+
+    return mClient_2_4->setPanelRefreshMode(display, mode);
+}
+
+V2_4::Error Composer::commitRefreshArea(Display display, int32_t x, int32_t y, int32_t h, int32_t w) {
+    using Error = V2_4::Error;
+    if (!mClient_2_4) {
+        return Error::UNSUPPORTED;
+    }
+
+    return mClient_2_4->commitRefreshArea(display, x, y, h, w);
+}
+V2_4::Error Composer::getSupportedContentTypes(Display displayId, std::vector* outSupportedContentTypes) {using Error = V2_4::Error;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 5408d5515..06cc105fa 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -231,6 +231,8 @@ public:VsyncPeriodChangeTimeline* outTimeline) = 0;virtual V2_4::Error setAutoLowLatencyMode(Display displayId, bool on) = 0;
+    virtual V2_4::Error setPanelRefreshMode(Display displayId, int32_t mode) = 0;
+    virtual V2_4::Error commitRefreshArea(Display displayId, int32_t x, int32_t y, int32_t h, int32_t w) = 0;virtual V2_4::Error getSupportedContentTypes(Display displayId,std::vector* outSupportedContentTypes) = 0;
@@ -480,6 +482,8 @@ public:const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,VsyncPeriodChangeTimeline* outTimeline) override;V2_4::Error setAutoLowLatencyMode(Display displayId, bool on) override;
+    V2_4::Error setPanelRefreshMode(Display displayId, int32_t mode) override;
+    V2_4::Error commitRefreshArea(Display displayId, int32_t x, int32_t y, int32_t h, int32_t w) override;V2_4::Error getSupportedContentTypes(Display displayId,std::vector* outSupportedContentTypes) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 940437f18..745d2c464 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -659,6 +659,16 @@ std::future Display::setDisplayBrightness(float brightness) {});}+Error Display::setPanelRefreshMode(int32_t mode) {
+    const auto intError = mComposer.setPanelRefreshMode(mId, mode);
+    return static_cast(intError);
+}
+
+Error Display::commitRefreshArea(int32_t x, int32_t y, int32_t h, int32_t w) {
+    const auto intError = mComposer.commitRefreshArea(mId, x, y, h, w);
+    return static_cast(intError);
+}
+Error Display::setAutoLowLatencyMode(bool on) {auto intError = mComposer.setAutoLowLatencyMode(mId, on);return static_cast(intError);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 469baf736..d76886f67 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -231,6 +231,8 @@ public:const hal::VsyncPeriodChangeConstraints& constraints,hal::VsyncPeriodChangeTimeline* outTimeline) = 0;[[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) = 0;
+    [[clang::warn_unused_result]] virtual hal::Error setPanelRefreshMode(int32_t mode) = 0;
+    [[clang::warn_unused_result]] virtual hal::Error commitRefreshArea(int32_t x, int32_t y, int32_t h, int32_t w) = 0;[[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(std::vector*) const = 0;[[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) = 0;
@@ -305,6 +307,8 @@ public:const hal::VsyncPeriodChangeConstraints& constraints,hal::VsyncPeriodChangeTimeline* outTimeline) override;hal::Error setAutoLowLatencyMode(bool on) override;
+    hal::Error setPanelRefreshMode(int32_t mode) override;
+    hal::Error commitRefreshArea(int32_t x, int32_t y, int32_t h, int32_t w) override;hal::Error getSupportedContentTypes(std::vector* outSupportedContentTypes) const override;hal::Error setContentType(hal::ContentType) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 910f99dc5..6832ad8ab 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -833,6 +833,32 @@ status_t HWComposer::setAutoLowLatencyMode(DisplayId displayId, bool on) {return NO_ERROR;}+status_t HWComposer::setPanelRefreshMode(DisplayId displayId, int32_t mode) {
+    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+    const auto error = mDisplayData[displayId].hwcDisplay->setPanelRefreshMode(mode);
+    if (error == hal::Error::UNSUPPORTED) {
+        RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+    }
+    if (error == hal::Error::BAD_PARAMETER) {
+        RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+    }
+    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+    return NO_ERROR;
+}
+
+status_t HWComposer::commitRefreshArea(DisplayId displayId, int32_t x, int32_t y, int32_t h, int32_t w) {
+    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+    const auto error = mDisplayData[displayId].hwcDisplay->commitRefreshArea(x, y, h, w);
+    if (error == hal::Error::UNSUPPORTED) {
+        RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+    }
+    if (error == hal::Error::BAD_PARAMETER) {
+        RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+    }
+    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+    return NO_ERROR;
+}
+status_t HWComposer::getSupportedContentTypes(DisplayId displayId, std::vector* outSupportedContentTypes) {RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index eb90ab2e2..77a564d71 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -206,6 +206,9 @@ public:const hal::VsyncPeriodChangeConstraints& constraints,hal::VsyncPeriodChangeTimeline* outTimeline) = 0;virtual status_t setAutoLowLatencyMode(DisplayId displayId, bool on) = 0;
+    // Sets T1000 refresh mode..
+    virtual status_t setPanelRefreshMode(DisplayId displayId, int32_t mode) = 0;
+    virtual status_t commitRefreshArea(DisplayId displayId, int32_t x, int32_t y, int32_t h, int32_t w) = 0;virtual status_t getSupportedContentTypes(DisplayId displayId, std::vector* outSupportedContentTypes) = 0;virtual status_t setContentType(DisplayId displayId, hal::ContentType contentType) = 0;
@@ -311,7 +314,7 @@ public:DisplayedFrameStats* outStats) override;std::future setDisplayBrightness(DisplayId displayId, float brightness) override;-    // Events handling ---------------------------------------------------------
+	// Events handling ---------------------------------------------------------// Returns stable display ID (and display name on connection of new or previously disconnected// display), or std::nullopt if hotplug event was ignored.
@@ -348,6 +351,8 @@ public:const hal::VsyncPeriodChangeConstraints& constraints,hal::VsyncPeriodChangeTimeline* outTimeline) override;status_t setAutoLowLatencyMode(DisplayId displayId, bool) override;
+    status_t setPanelRefreshMode(DisplayId displayId, int32_t mode) override;
+    status_t commitRefreshArea(DisplayId displayId, int32_t x, int32_t y, int32_t h, int32_t w) override;status_t getSupportedContentTypes(DisplayId displayId, std::vector*) override;status_t setContentType(DisplayId displayId, hal::ContentType) override;diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0d07abb1d..017caae08 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1562,6 +1562,26 @@ void SurfaceFlinger::setAutoLowLatencyMode(const sp& displayToken, bool}));}+void SurfaceFlinger::setPanelRefreshMode(const sp& displayToken, int32_t mode) {
+    static_cast(schedule([=]() MAIN_THREAD {
+        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+            getHwComposer().setPanelRefreshMode(*displayId, mode);
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        }
+    }));
+}
+
+void SurfaceFlinger::commitRefreshArea(const sp& displayToken, int32_t x, int32_t y, int32_t h, int32_t w) {
+    static_cast(schedule([=]() MAIN_THREAD {
+        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+            getHwComposer().commitRefreshArea(*displayId, x, y, h, w);
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        }
+    }));
+}
+status_t SurfaceFlinger::getGameContentTypeSupport(const sp& displayToken,bool* outSupport) const {if (!displayToken) {
@@ -5949,6 +5969,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {case SET_ACTIVE_COLOR_MODE:case GET_AUTO_LOW_LATENCY_MODE_SUPPORT:case SET_AUTO_LOW_LATENCY_MODE:
+        case SET_PANEL_REFRESH_MODE:
+        case COMMIT_REFRESH_AREA:case GET_GAME_CONTENT_TYPE_SUPPORT:case SET_GAME_CONTENT_TYPE:case INJECT_VSYNC:
@@ -6045,9 +6067,9 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) {code == IBinder::SYSPROPS_TRANSACTION) {return OK;}
-    // Numbers from 1000 to 1036 and 20000 to 20002 are currently used for backdoors. The code
+    // Numbers from 1000 to 1036 and 20000 to 20007 are currently used for backdoors. The code// in onTransact verifies that the user is root, and has access to use SF.
-    if ((code >= 1000 && code <= 1036) || (code >= 20000 && code <= 20002)) {
+    if ((code >= 1000 && code <= 1036) || (code >= 20000 && code <= 20007)) {ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);return OK;}
@@ -6549,6 +6571,35 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r#endifreturn NO_ERROR;}
+            case 20006: {
+                int32_t mode = 0;
+                Mutex::Autolock lock(mStateLock);
+                const auto displayId = getInternalDisplayIdLocked();
+                if (data.readInt32(&mode) != NO_ERROR) {
+                    err = BAD_TYPE;
+                    ALOGE("Invalid 32-bit signed-int wider-mode t1000 fresh mode.");
+                    break;
+                }
+
+                ALOGE("====== SF get T1000 fresh mode value: %d, will set to hw layer.", mode);
+                getHwComposer().setPanelRefreshMode(*displayId, mode);
+
+                return NO_ERROR;
+            }
+            case 20007: {
+                int32_t x, y, h, w = 0;
+                Mutex::Autolock lock(mStateLock);
+                const auto displayId = getInternalDisplayIdLocked();
+                x = data.readInt32();
+                y = data.readInt32();
+                h = data.readInt32();
+                w = data.readInt32();
+
+                ALOGE("====== SF get T1000 fresh area value: %d,%d,%d,%d will set to hw layer.",x, y, h, w);
+                getHwComposer().commitRefreshArea(*displayId, x, y, h, w);
+
+                return NO_ERROR;
+            }}}return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6c7fb3419..4499a7e2e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -532,6 +532,8 @@ private:status_t getAutoLowLatencyModeSupport(const sp& displayToken,bool* outSupported) const override;void setAutoLowLatencyMode(const sp& displayToken, bool on) override;
+    void setPanelRefreshMode(const sp& displayToken, int32_t mode) override;
+    void commitRefreshArea(const sp& displayToken, int32_t x, int32_t y, int32_t h, int32_t w) override;status_t getGameContentTypeSupport(const sp& displayToken,bool* outSupported) const override;void setGameContentType(const sp& displayToken, bool on) override;

以上只是sf native层面的扩展,还需要通过HIDL接口扩展到HW,从而实现通信,首先实现interface定义扩展:

diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal
index 9e3cf0e08..72d6d7d60 100644
--- a/graphics/composer/2.4/IComposerClient.hal
+++ b/graphics/composer/2.4/IComposerClient.hal
@@ -279,6 +279,34 @@ interface IComposerClient extends @2.3::IComposerClient {setAutoLowLatencyMode(Display display, bool on)generates (Error error);+    /**
+     * Set the display refresh mode.
+     *
+     * If the display is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If
+     * the display is internally connected and a custom low latency mode is available, that should
+     * be triggered.
+     *
+     * This function should only be called if the display reports support for
+     *
+     * @return error is NONE upon success. Otherwise,
+     */
+    setPanelRefreshMode(Display display, int32_t mode)
+        generates (Error error);
+
+    /**
+     * Set the refresh area.
+     *
+     * If the display is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If
+     * the display is internally connected and a custom low latency mode is available, that should
+     * be triggered.
+     *
+     * This function should only be called if the display reports support for
+     *
+     * @return error is NONE upon success. Otherwise,
+     */
+    commitRefreshArea(Display display, int32_t x, int32_t y, int32_t h, int32_t w)
+        generates (Error error);
+/*** Provides a list of all the content types supported by this display (any of* ContentType::{GRAPHICS, PHOTO, CINEMA, GAME}). This list must not change after
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
index c88906914..b9ac48a03 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h
@@ -150,6 +150,14 @@ class ComposerClientImpl : public V2_3::hal::detail::ComposerClientImplsetAutoLowLatencyMode(display, on);}+    Return setPanelRefreshMode(Display display, int32_t mode) override {
+        return mHal->setPanelRefreshMode(display, mode);
+    }
+
+    Return commitRefreshArea(Display display, int32_t x, int32_t y, int32_t h, int32_t w) override {
+        return mHal->commitRefreshArea(display, x, y, h, w);
+    }
+Return getSupportedContentTypes(Display display, IComposerClient::getSupportedContentTypes_cb hidl_cb) override {std::vector supportedContentTypes;
diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
index 58991c1d8..390d7f05d 100644
--- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
+++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerHal.h
@@ -69,6 +69,8 @@ class ComposerHal : public V2_3::hal::ComposerHal {const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,VsyncPeriodChangeTimeline* timeline) = 0;virtual Error setAutoLowLatencyMode(Display display, bool on) = 0;
+    virtual Error setPanelRefreshMode(Display display, int32_t mode) = 0;
+    virtual Error commitRefreshArea(Display display, int32_t x, int32_t y, int32_t h, int32_t w) = 0;virtual Error getSupportedContentTypes(Display display,std::vector* outSupportedContentTypes) = 0;
diff --git a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
index d28e00625..5eac92438 100644
--- a/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
+++ b/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcHal.h
@@ -180,6 +180,30 @@ class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl {return Error::NONE;}+    Error setPanelRefreshMode(Display display, int32_t mode) override {
+        if (!mDispatch.setPanelRefreshMode) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t error = mDispatch.setPanelRefreshMode(mDevice, display, mode);
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast(error);
+        }
+        return Error::NONE;
+    }
+
+    Error commitRefreshArea(Display display, int32_t x, int32_t y, int32_t h, int32_t w) override {
+        if (!mDispatch.commitRefreshArea) {
+            return Error::UNSUPPORTED;
+        }
+
+        int32_t error = mDispatch.commitRefreshArea(mDevice, display, x, y, h, w);
+        if (error != HWC2_ERROR_NONE) {
+            return static_cast(error);
+        }
+        return Error::NONE;
+    }
+Error getSupportedContentTypes(Display display,std::vector* outSupportedContentTypes) override {
@@ -317,6 +341,10 @@ class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl {&mDispatch.getDisplayConnectionType);this->initOptionalDispatch(HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE,&mDispatch.setAutoLowLatencyMode);
+        this->initOptionalDispatch(HWC2_FUNCTION_SET_PANEL_REFRESH_MODE,
+                                   &mDispatch.setPanelRefreshMode);
+        this->initOptionalDispatch(HWC2_FUNCTION_COMMIT_REFRESH_AREA,
+                                   &mDispatch.commitRefreshArea);this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,&mDispatch.getSupportedContentTypes);this->initOptionalDispatch(HWC2_FUNCTION_SET_CONTENT_TYPE, &mDispatch.setContentType);
@@ -376,6 +404,8 @@ class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl {HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD getDisplayVsyncPeriod;HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS setActiveConfigWithConstraints;HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE setAutoLowLatencyMode;
+        HWC2_PFN_SET_PANEL_REFRESH_MODE setPanelRefreshMode;
+        HWC2_PFN_COMMIT_REFRESH_AREA commitRefreshArea;HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES getSupportedContentTypes;HWC2_PFN_SET_CONTENT_TYPE setContentType;HWC2_PFN_GET_CLIENT_TARGET_PROPERTY getClientTargetProperty;

这个时候做一次增量编译,会提示如下两个编译错误,按如下方式修改解决:

修改如上几个地方后,编译报错

错误一、which does not match hash on record. This interface has been frozen. Do not change it!ERROR: output handler failed.
HIDL c++-sources: hardware/interfaces/light/2.0/types.hal hardware/interfaces/light/2.0/ILight.hal hardware/interfaces/current.txt => 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0_genc++/gen/android/hardware/light/2.0/LightAll.cpp'
FAILED: out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0_genc++/gen/android/hardware/light/2.0/LightAll.cpp out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0_genc++/gen/android/hardware/light/2.0/types.cpp
rm -rf out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0_genc++/gen && out/soong/host/linux-x86/bin/hidl-gen -R -p . -d out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0_genc++/gen/android/hardware/light/2.0/LightAll.cpp.d -o out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0_genc++/gen -L c++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.light@2.0
ERROR: android.hardware.light@2.0::types has hash cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e which does not match hash on record. This interface has been frozen. Do not change it!
ERROR: Could not parse android.hardware.light@2.0::types. Aborting.


原因:Android P 开始,Google 对 Hidl 有了严格的限制。Google release 出来的 hidl 接口不允许修改。

需要重新生成修改 hardware 对应的 hashcode,错误中已经包含新的 hashcode 值 cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e

如果没有此 hashcode 值,可以通过指令 hidl-gen -L hash -r 来生成,得到和错误提示中的hash值一模一样

$ hidl-gen -L hash -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.light@2.0::types
cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e android.hardware.light@2.0::types

将刚刚得到的新 hashcode 值更新到 hardware/interfaces/current.txt

可直接在文档末尾增加

cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e android.hardware.light@2.0::types

错误二、error: VNDK library: android.hardware.light@2.0’s ABI has INCOMPATIBLE CHANGES

Please check compatibility report at: out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_cortex-a53_vendor_shared/android.hardware.light@2.0.so.abidiffInstall: out/target/product/full_171_bsp/system/lib64/vndk-29/android.hardware.keymaster@3.0.so
//hardware/interfaces/light/2.0:android.hardware.light@2.0 header-abi-diff android.hardware.light@2.0.so.abidiff
FAILED: out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_cortex-a53_vendor_shared/android.hardware.light@2.0.so.abidiff
(prebuilts/clang-tools/linux-x86/bin/header-abi-diff -allow-unreferenced-changes -allow-unreferenced-elf-symbol-changes -lib android.hardware.light@2.0 -arch arm64 -o 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_cortex-a53_vendor_shared/android.hardware.light@2.0.so.abidiff' -new 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_cortex-a53_vendor_shared/android.hardware.light@2.0.so.lsdump' -old prebuilts/abi-dumps/vndk/29/64/arm64_armv8-a/source-based/android.hardware.light@2.0.so.lsdump)|| (echo 'error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py  -l android.hardware.light@2.0' && (mkdir -p $DIST_DIR/abidiffs && cp 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_cortex-a53_vendor_shared/android.hardware.light@2.0.so.abidiff' $DIST_DIR/abidiffs/) && exit 1)
******************************************************
error: VNDK library: android.hardware.light@2.0's ABI has INCOMPATIBLE CHANGES Please check compatibility report at: out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_cortex-a53_vendor_shared/android.hardware.light@2.0.so.abidiff
******************************************************
error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py  -l android.hardware.light@2.0根据提示执行指令 development/vndk/tools/header-checker/utils/create_reference_dumps.py -l android.hardware.light@2.0 ,发现报错$ development/vndk/tools/header-checker/utils/create_reference_dumps.py -l android.hardware.light@2.0
Removing reference dumps...
removing /platform/prebuilts/abi-dumps/vndk/28/32/arm_armv7-a-neon/source-based/android.hardware.gnss@1.0.so.lsdump.gz
removing /platform/prebuilts/abi-dumps/ndk/28/32/arm_armv7-a-neon/source-based/android.hardware.gnss@1.0.so.lsdump.gz
making libs for product: aosp_arm_ab
Traceback (most recent call last):File "development/vndk/tools/header-checker/utils/create_reference_dumps.py", line 224, in main()File "development/vndk/tools/header-checker/utils/create_reference_dumps.py", line 215, in mainmake_libs_for_product(args.libs, args.llndk, product)File "development/vndk/tools/header-checker/utils/create_reference_dumps.py", line 97, in make_libs_for_productmake_libraries(libs, product, llndk_mode)File "/platform/development/vndk/tools/header-checker/utils/utils.py", line 146, in make_librariesmake_targets(lib_targets, product)File "/platform/development/vndk/tools/header-checker/utils/utils.py", line 137, in make_targetsstderr=subprocess.STDOUT)File "/usr/lib/python3.5/subprocess.py", line 581, in check_callraise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['build/soong/soong_ui.bash', '--make-mode', '-j', 'android.hardware.gnss@1.0.vendor', 'TARGET_PRODUCT=aosp_arm_ab']' returned non-zero exit status 1看到 making libs for product: aosp_arm_ab 这行,这个是因为我的项目 product名字不一样导致的,加上参数-product product_name 即可,product_name 是你的项目的 product 名称。development/vndk/tools/header-checker/utils/create_reference_dumps.py -l android.hardware.light@2.0 -product full_171_bspAllowBuildBrokenUsesNetwork: trueBuildBrokenUsesNetwork: true
//hardware/interfaces/light/2.0:android.hardware.light@2.0 header-abi-linker android.hardware.light@2.0.so.lsdump [arm]
Creating dumps for target_arch: arm and variant  armv8-a
Created abi dump at /prebuilts/abi-dumps/vndk/29/64/arm_armv8-a/source-based/android.hardware.light@2.0.so.lsdump
Creating dumps for target_arch: arm64 and variant  armv8-a
Created abi dump at /prebuilts/abi-dumps/vndk/29/64/arm64_armv8-a/source-based/android.hardware.light@2.0.so.lsdumpmsg: Processed 2 libraries in  14.642458236217498  minutes

添加头文件定义:

diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h
index 76122a57..698ae498 100644
--- a/include/hardware/hwcomposer2.h
+++ b/include/hardware/hwcomposer2.h
@@ -304,6 +304,8 @@ typedef enum {HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD,HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE,
+    HWC2_FUNCTION_SET_PANEL_REFRESH_MODE,
+    HWC2_FUNCTION_COMMIT_REFRESH_AREA,HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,HWC2_FUNCTION_SET_CONTENT_TYPE,HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY,
@@ -666,6 +668,8 @@ static inline const char* getFunctionDescriptorName(case HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD: return "GetDisplayVsyncPeriod";case HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS: return "SetActiveConfigWithConstraints";case HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE: return "SetAutoLowLatencyMode";
+        case HWC2_FUNCTION_SET_PANEL_REFRESH_MODE: return "SetPanelRefreshMode";
+        case HWC2_FUNCTION_COMMIT_REFRESH_AREA: return "CommitRefreshArea";case HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES: return "GetSupportedContentTypes";case HWC2_FUNCTION_SET_CONTENT_TYPE: return "SetContentType";case HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY: return "GetClientTargetProperty";
@@ -946,6 +950,8 @@ enum class FunctionDescriptor : int32_t {GetDisplayVsyncPeriod = HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD,SetActiveConfigWithConstraints = HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,SetAutoLowLatencyMode = HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE,
+    SetPanelRefreshMode = HWC2_FUNCTION_SET_PANEL_REFRESH_MODE,
+    CommitRefreshArea = HWC2_FUNCTION_COMMIT_REFRESH_AREA,GetSupportedContentTypes = HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,SetContentType = HWC2_FUNCTION_SET_CONTENT_TYPE,GetClientTargetProperty = HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY,
@@ -3004,6 +3010,36 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS)(typedef int32_t /*hwc_error_t*/ (*HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE)(hwc2_device_t* device,hwc2_display_t display, bool on);+/* setPanelRefreshMode(displayToken, mode)
+ * Descriptor: HWC2_FUNCTION_SET_PANEL_REFRESH_MODE
+ * Optional for HWC2 devices
+ *
+ * setAutoLowLatencyMode requests that the display goes into low latency mode. If the display
+ * is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If the display is
+ * internally connected, then a custom low latency mode should be triggered (if available).
+ *
+ * Returns HWC2_ERROR_NONE or one of the following errors:
+ *   HWC2_ERROR_BAD_DISPLAY - when the display is invalid, or
+ *   HWC2_ERROR_UNSUPPORTED - when the display does not support any low latency mode
+ */
+typedef int32_t /*hwc_error_t*/ (*HWC2_PFN_SET_PANEL_REFRESH_MODE)(hwc2_device_t* device,
+        hwc2_display_t display, int32_t mode);
+
+/* commitRefreshArea(displayToken, x, y, h, w)
+ * Descriptor:HWC2_FUNCTION_COMMIT_REFRESH_AREA 
+ * Optional for HWC2 devices
+ *
+ * setAutoLowLatencyMode requests that the display goes into low latency mode. If the display
+ * is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If the display is
+ * internally connected, then a custom low latency mode should be triggered (if available).
+ *
+ * Returns HWC2_ERROR_NONE or one of the following errors:
+ *   HWC2_ERROR_BAD_DISPLAY - when the display is invalid, or
+ *   HWC2_ERROR_UNSUPPORTED - when the display does not support any low latency mode
+ */
+typedef int32_t /*hwc_error_t*/ (*HWC2_PFN_COMMIT_REFRESH_AREA)(hwc2_device_t* device,
+        hwc2_display_t display, int32_t x, int32_t y, int32_t h, int32_t w);
+/* getSupportedContentTypes(..., outSupportedContentTypes)* Descriptor: HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES* Optional for HWC2 devices

最后扩展hw服务的接口在android/hardware/qcom/display/sdm/libs/hwc2目录:

diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 21be352f..e4f2fef8 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1191,6 +1191,22 @@ int32_t HWCSession::SetAutoLowLatencyMode(hwc2_device_t *device, hwc2_display_treturn HWC2_ERROR_UNSUPPORTED;}+int32_t HWCSession::SetPanelRefreshMode(hwc2_device_t *device, hwc2_display_t display, int32_t mode) {
+  DLOGE("====== HWCSession::SetPanelRefreshMode get from fw: %d .", mode);
+  if (!device || display >= HWCCallbacks::kNumDisplays) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+  return HWC2_ERROR_NONE;
+}
+
+int32_t HWCSession::CommitRefreshArea(hwc2_device_t *device, hwc2_display_t display, int32_t x, int32_t y, int32_t h, int32_t w) {
+  DLOGE("====== HWCSession::CommitRefreshArea get from fw: x= %d y= %d h= %d w= %d\n .", x, y, h, w);
+  if (!device || display >= HWCCallbacks::kNumDisplays) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+  return HWC2_ERROR_NONE;
+}
+int32_t HWCSession::GetSupportedContentTypes(hwc2_device_t *device, hwc2_display_t display,uint32_t *count, uint32_t *contentTypes) {contentTypes = {};
@@ -1382,6 +1398,10 @@ hwc2_function_pointer_t HWCSession::GetFunction(struct hwc2_device *device,(HWCSession::SetActiveConfigWithConstraints);case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:return AsFP(HWCSession::SetAutoLowLatencyMode);
+    case HWC2::FunctionDescriptor::SetPanelRefreshMode:
+      return AsFP(HWCSession::SetPanelRefreshMode);
+    case HWC2::FunctionDescriptor::CommitRefreshArea:
+      return AsFP(HWCSession::CommitRefreshArea);case HWC2::FunctionDescriptor::GetSupportedContentTypes:return AsFP(HWCSession::GetSupportedContentTypes);case HWC2::FunctionDescriptor::SetContentType:
@@ -1808,6 +1828,15 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pastatus = SetPanelLuminanceAttributes(input_parcel);break;+    case qService::IQService::SET_DISPLAY_REFRESH_MODE:
+      if (!input_parcel) {
+        DLOGE("QService command SET_DISPLAY_REFRESH_MODE = %d: input_parcel needed.", command);
+        break;
+      }
+      DLOGE("====== HW session rec SET_DISPLAY_REFRESH_MODE cmd");
+      //status = SetPanelLuminanceAttributes(input_parcel);
+      break;
+case qService::IQService::SET_COLOR_MODE_FROM_CLIENT:if (!input_parcel) {DLOGE("QService command = %d: input_parcel needed.", command);
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 5931a5d9..c0c3bd45 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -233,6 +233,8 @@ class HWCSession : hwc2_device_t, HWCUEventListener, public qClient::BnQClient,static int32_t GetDozeSupport(hwc2_device_t *device, hwc2_display_t display,int32_t *out_support);static int32_t SetAutoLowLatencyMode(hwc2_device_t *device, hwc2_display_t display, bool on);
+  static int32_t SetPanelRefreshMode(hwc2_device_t *device, hwc2_display_t display, int32_t mode);
+  static int32_t CommitRefreshArea(hwc2_device_t *device, hwc2_display_t display, int32_t x, int32_t y, int32_t h, int32_t w);static int32_t GetSupportedContentTypes(hwc2_device_t *device, hwc2_display_t display,uint32_t *count, uint32_t *contentTypes);static int32_t SetContentType(hwc2_device_t *device, hwc2_display_t display,int32_t type);

刷机验证即可~~~

顺利的话会得到如下日志:

11-21 11:20:54.105  1050  1050 I SystemServerTiming: StartSystemUpdateManagerService
11-21 11:20:54.106  1050  1050 I SystemUpdateManagerService: No existing info file /data/system/system-update-info.xml
11-21 11:20:54.107  1050  1050 D SystemServerTiming: StartSystemUpdateManagerService took to complete: 2ms
11-21 11:20:54.108  1050  1050 I SystemServerTiming: StartUpdateLockService
11-21 11:20:54.109  1050  1050 D SystemServerTiming: StartUpdateLockService took to complete: 1ms
11-21 11:20:54.109  1050  1050 I SystemServerTiming: ====== StartHandWriteManagerService
11-21 11:20:54.109  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: initializing......
11-21 11:20:54.110  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: 000000......
11-21 11:20:54.110  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: 111111......
11-21 11:20:54.110  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: 222222......
11-21 11:20:54.111  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: 333333......
11-21 11:20:54.111  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: data init                                                                                                                                                                                                    
11-21 11:20:54.111  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: 6666666......
11-21 11:20:54.111   818  1400 E SurfaceFlinger: ====== SF get T1000 fresh mode value: 2, will set to hw layer.
11-21 11:20:54.112   715   715 E SDM     : HWCSession::SetPanelRefreshMode: ====== HWCSession::SetPanelRefreshMode get from fw: 2 .
11-21 11:20:54.112  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init JNI: 77777777......
11-21 11:20:54.113   818  1400 E SurfaceFlinger: ====== SF get T1000 fresh area value: 100,100,100,100 will set to hw layer.
11-21 11:20:54.113   715   715 E SDM     : HWCSession::CommitRefreshArea: ====== HWCSession::CommitRefreshArea get from fw: x= 100 y= 100 h= 100 w= 100
11-21 11:20:54.113   715   715 E SDM     :  .  
11-21 11:20:54.113  1050  1050 E HandWrite_JNI: ====== HandWriteServiceNative_Init already write cmd to hwc service
11-21 11:20:54.115  1050  1050 D SystemServerTiming: ====== StartHandWriteManagerService took to complete: 6ms
11-21 11:20:54.116  1050  1050 I SystemServerTiming: StartNotificationManager
11-21 11:20:54.116  1050  1050 I SystemServiceManager: Starting com.android.server.notification.NotificationManagerService
01-01 00:24:43.550     0     0 I chatty  : uid=0(root) logd identical 107 lines 
01-01 00:24:43.559     0     0 I bad ioctl: -1072934383

可以看到“======”标示的内容,从自定义服务开始到SF日志,到最终HW层扩展接口拿到传递的数据值证明接口通了~~~~完事大吉!!!!!!

Mark一下,本文只做数据通路走通,可参考实现自己的控制和数据传输接口!

相关内容

热门资讯

笔试强训48天——day29 文章目录一. 单选1. 某台微机安装的是 64 位操作系统,“ 64 位”指的是&#x...
PyTorch初学者指南:数据... PyTorch初学者指南:数据操作 文章目录PyTorch初学者指南:数...
基于Android的班级圈系统... 需求信息: 1.前台安卓app,后台web管理 2.用户由教师家长学生...
【MySQL Shell】9.... 配置实例后,通过完成以下步骤创建 InnoDB ReplicaSet: ...
【深度学习笔记】手动推导反向传... 问题 现在才意识到,卷积神经网络在不同的层上的反向传播的计算公式不一样,之前一直按照全连接层的那种简...
实战五十六:基于机器学习的上海... 本文主要分析影响房价的因素,数据来源为链家网,机器学习模型的使用中,采用了三种线性模型,一种非线性模...
如何修复u盘损坏的文件?   由于U盘经常会在各种不同的电脑上使用,这让它很容易出现一些问题,如u...
排序算法_ 一、选择排序题目arr[0~N-1]范围上,找到最小值所在的位置...
监控圈子行业黑话 文章目录监控圈子行业黑话监控监控系统监控指标全局唯一字符串作为指标标识标签集的组合作为指标标识优雅高...
C++高精度运算(加减乘除) C++中在int 是32位bit是2^32-1。 C/C++基础数字...