Android11添加AIDL系统服务及HIDL接口服务

软件平台: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: [email protected] 
	* 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:[email protected] 
	* 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();
		}*/
    }

    @Override
    public 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();

        }

    }

    @Override
    public void commitRefreshArea(int x, int y, int h, int w) {
        HandWriteServiceNative_commitRefreshArea(x, y, h, w);
    }
}

向SystemServer完成注册:

diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 3d8328bd193..1279df76dd5 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -89,6 +89,7 @@ import com.android.internal.util.ConcurrentUtils;
 import com.android.internal.util.EmergencyAffordanceManager;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.widget.ILockSettings;
+import com.android.server.HandWriteManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.appbinding.AppBindingService;
 import com.android.server.attention.AttentionManagerService;
@@ -1614,6 +1615,16 @@ public final class SystemServer {
             }
             t.traceEnd();
 
+            t.traceBegin("StartHandWriteManagerService");
+            try {
+                Slog.i(TAG, "HandWriteManagerService is create");
+                ServiceManager.addService(Context.HAND_WRITE_SERVICE,
+                        new HandWriteManagerService(context));
+            } catch (Throwable e) {
+                reportWtf("starting HandWriteManagerService", e);
+            }
+            t.traceEnd();
+
             t.traceBegin("StartNotificationManager");
             mSystemServiceManager.startService(NotificationManagerService.class);
             SystemNotificationChannels.removeDeprecated(context);
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: [email protected] 
	> 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 first
        data1.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 first
        data.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 first
        data.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& disp
     return 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:
     // #getAutoLowLatencyModeSupport
     static 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 type
     static 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
 #endif
                 return 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/[email protected]_genc++/gen/android/hardware/light/2.0/LightAll.cpp'
FAILED: out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]_genc++/gen/android/hardware/light/2.0/LightAll.cpp out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]_genc++/gen/android/hardware/light/2.0/types.cpp
rm -rf out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]_genc++/gen && out/soong/host/linux-x86/bin/hidl-gen -R -p . -d out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]_genc++/gen/android/hardware/light/2.0/LightAll.cpp.d -o out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]_genc++/gen -L c++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport [email protected]
ERROR: [email protected]::types has hash cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e which does not match hash on record. This interface has been frozen. Do not change it!
ERROR: Could not parse [email protected]::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 [email protected]::types
cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e [email protected]::types

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

可直接在文档末尾增加

cd082c47c3940f2c4d4ef489c9f34e0c737dfcbd7dd09e0e270563e699a9d91e [email protected]::types

错误二、error: VNDK library: [email protected]’s ABI has INCOMPATIBLE CHANGES

Please check compatibility report at: out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]/android_arm64_armv8-a_cortex-a53_vendor_shared/[email protected]

Install: out/target/product/full_171_bsp/system/lib64/vndk-29/[email protected]
//hardware/interfaces/light/2.0:[email protected] header-abi-diff [email protected]
FAILED: out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]/android_arm64_armv8-a_cortex-a53_vendor_shared/[email protected]
(prebuilts/clang-tools/linux-x86/bin/header-abi-diff -allow-unreferenced-changes -allow-unreferenced-elf-symbol-changes -lib [email protected] -arch arm64 -o 'out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]/android_arm64_armv8-a_cortex-a53_vendor_shared/[email protected]' -new 'out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]/android_arm64_armv8-a_cortex-a53_vendor_shared/[email protected]' -old prebuilts/abi-dumps/vndk/29/64/arm64_armv8-a/source-based/[email protected])|| (echo 'error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py  -l [email protected]' && (mkdir -p $DIST_DIR/abidiffs && cp 'out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]/android_arm64_armv8-a_cortex-a53_vendor_shared/[email protected]' $DIST_DIR/abidiffs/) && exit 1)
******************************************************
error: VNDK library: [email protected]'s ABI has INCOMPATIBLE CHANGES Please check compatibility report at: out/soong/.intermediates/hardware/interfaces/light/2.0/[email protected]/android_arm64_armv8-a_cortex-a53_vendor_shared/[email protected]
******************************************************
error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py  -l [email protected]

根据提示执行指令 development/vndk/tools/header-checker/utils/create_reference_dumps.py -l [email protected] ,发现报错

$ development/vndk/tools/header-checker/utils/create_reference_dumps.py -l [email protected]
Removing reference dumps...
removing /platform/prebuilts/abi-dumps/vndk/28/32/arm_armv7-a-neon/source-based/[email protected]
removing /platform/prebuilts/abi-dumps/ndk/28/32/arm_armv7-a-neon/source-based/[email protected]
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 main
    make_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_product
    make_libraries(libs, product, llndk_mode)
  File "/platform/development/vndk/tools/header-checker/utils/utils.py", line 146, in make_libraries
    make_targets(lib_targets, product)
  File "/platform/development/vndk/tools/header-checker/utils/utils.py", line 137, in make_targets
    stderr=subprocess.STDOUT)
  File "/usr/lib/python3.5/subprocess.py", line 581, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['build/soong/soong_ui.bash', '--make-mode', '-j', '[email protected]', '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 [email protected] -product full_171_bsp

AllowBuildBrokenUsesNetwork: true
 BuildBrokenUsesNetwork: true
//hardware/interfaces/light/2.0:[email protected] header-abi-linker [email protected] [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/[email protected]
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/[email protected]

msg: 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_t
   return 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::Pa
       status = 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一下,本文只做数据通路走通,可参考实现自己的控制和数据传输接口!

你可能感兴趣的:(Framework,HIDL,AIDL,Hardware,SurfaceFlinger,JNI)