Add AIDL API for PowerHAL to send session updates with FMQ

This patch adds a set of APIs to PowerHAL to enable hint session
communication via FMQ, to reduce both binder overhead and call latency
moving forward.

Bug: 315894228
Test: atest VtsHalPowerTargetTest
Change-Id: I56f89322c7706ab68e640542caf5b70eef36c451
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index 7643926..8900fb8 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -28,11 +28,20 @@
         "android/hardware/power/*.aidl",
     ],
     stability: "vintf",
+    imports: [
+        "android.hardware.common.fmq-V1",
+        "android.hardware.common-V2",
+    ],
     backend: {
         cpp: {
+            enabled: false,
+        },
+        ndk: {
             enabled: true,
         },
         java: {
+            sdk_version: "module_current",
+            enabled: true,
             platform_apis: true,
         },
     },
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
new file mode 100644
index 0000000..d3caca4
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@VintfStability
+parcelable ChannelConfig {
+  android.hardware.common.fmq.MQDescriptor<android.hardware.power.ChannelMessage,android.hardware.common.fmq.SynchronizedReadWrite> channelDescriptor;
+  @nullable android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> eventFlagDescriptor;
+  int readFlagBitmask;
+  int writeFlagBitmask;
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
new file mode 100644
index 0000000..25f01c0
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@FixedSize @VintfStability
+parcelable ChannelMessage {
+  int sessionID;
+  android.hardware.power.ChannelMessage.ChannelMessageContents data;
+  @FixedSize @VintfStability
+  union ChannelMessageContents {
+    int[20] tids = {(-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */, (-1) /* -1 */};
+    long targetDuration;
+    android.hardware.power.SessionHint hint;
+    android.hardware.power.ChannelMessage.ChannelMessageContents.SessionModeSetter mode;
+    android.hardware.power.WorkDurationFixedV1 workDuration;
+    @FixedSize @VintfStability
+    parcelable SessionModeSetter {
+      android.hardware.power.SessionMode modeInt;
+      boolean enabled;
+    }
+  }
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
index ae03313..8acdaf2 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
@@ -40,4 +40,7 @@
   boolean isBoostSupported(in android.hardware.power.Boost type);
   android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos);
   long getHintSessionPreferredRate();
+  android.hardware.power.IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds, in long durationNanos, in android.hardware.power.SessionTag tag, out android.hardware.power.SessionConfig config);
+  android.hardware.power.ChannelConfig getSessionChannel(in int tgid, in int uid);
+  oneway void closeSessionChannel(in int tgid, in int uid);
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
index 6bc663e..010f815 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl
@@ -42,4 +42,5 @@
   oneway void sendHint(android.hardware.power.SessionHint hint);
   void setThreads(in int[] threadIds);
   oneway void setMode(android.hardware.power.SessionMode type, boolean enabled);
+  android.hardware.power.SessionConfig getSessionConfig();
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
new file mode 100644
index 0000000..b03cfb2
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@VintfStability
+parcelable SessionConfig {
+  long id;
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
new file mode 100644
index 0000000..80848a4
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@Backing(type="int") @VintfStability
+enum SessionTag {
+  OTHER,
+  SURFACEFLINGER,
+  HWUI,
+  GAME,
+}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
new file mode 100644
index 0000000..8cd246d
--- /dev/null
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.power;
+@FixedSize @VintfStability
+parcelable WorkDurationFixedV1 {
+  long timeStampNanos;
+  long durationNanos;
+  long workPeriodStartTimestampNanos;
+  long cpuDurationNanos;
+  long gpuDurationNanos;
+}
diff --git a/power/aidl/android/hardware/power/ChannelConfig.aidl b/power/aidl/android/hardware/power/ChannelConfig.aidl
new file mode 100644
index 0000000..4da292e
--- /dev/null
+++ b/power/aidl/android/hardware/power/ChannelConfig.aidl
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.power.ChannelMessage;
+
+@VintfStability
+parcelable ChannelConfig {
+    /**
+     * The message queue descriptor that provides the information necessary for
+     * a client to write to this channel.
+     */
+    MQDescriptor<ChannelMessage, SynchronizedReadWrite> channelDescriptor;
+
+    /**
+     * A message queue descriptor used to pass an optional event flag to clients,
+     * used to synchronize multiple message queues using the same flag. If not
+     * defined, the flag from the channelDescriptor should be used.
+     */
+    @nullable MQDescriptor<byte, SynchronizedReadWrite> eventFlagDescriptor;
+
+    /**
+     * The read flag bitmask to be used with the event flag, specifying the
+     * bits used by this channel to mark that the buffer has been read from.
+     * If set to 0, the default bitmask will be used.
+     */
+    int readFlagBitmask;
+
+    /**
+     * The write flag bitmask to be used with the event flag, specifying the
+     * bits used by this channel to mark that the buffer has been written to.
+     * If set to 0, the default bitmask will be used.
+     */
+    int writeFlagBitmask;
+}
diff --git a/power/aidl/android/hardware/power/ChannelMessage.aidl b/power/aidl/android/hardware/power/ChannelMessage.aidl
new file mode 100644
index 0000000..4747d90
--- /dev/null
+++ b/power/aidl/android/hardware/power/ChannelMessage.aidl
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.SessionHint;
+import android.hardware.power.SessionMode;
+import android.hardware.power.WorkDurationFixedV1;
+
+/**
+ * Data sent through the FMQ must follow this structure. It's important to note
+ * that such data may come from the app itself, so the HAL must validate all
+ * data received through this interface, and reject any calls not guaranteed to be
+ * valid. Each of the types defined in the inner union maps to an equivalent call
+ * on IPowerHintSession, and is merely being used to expedite the use of that API
+ * in cases where it is safe to bypass the HintManagerService.
+ */
+@FixedSize
+@VintfStability
+parcelable ChannelMessage {
+    /**
+     * The ID of the specific session sending the hint, used to enable a single
+     * channel to be multiplexed across all sessions in a single process.
+     */
+    int sessionID;
+
+    /**
+     * A union defining the different messages that can be passed through the
+     * channel. Each type corresponds to a different call in IPowerHintSession.
+     */
+    ChannelMessageContents data;
+
+    @FixedSize
+    @VintfStability
+    union ChannelMessageContents {
+        /**
+         * List of TIDs for this session to change to. Can be used in cases
+         * where HintManagerService is not needed to validate the TIDs, such as
+         * when all TIDs directly belong to the process that owns the session.
+         */
+        int[20] tids = {
+                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+        /**
+         * Setting this field will update the session’s target duration, equivalent
+         * to calling updateTargetWorkDuration(targetDuration).
+         */
+        long targetDuration;
+
+        /**
+         * Setting this field will send a hint to the session, equivalent to
+         * calling sendHint(hint).
+         */
+        SessionHint hint;
+
+        /**
+         * Setting this field will send a hint to the session, equivalent to
+         * calling setMode(mode.modeInt, mode.enabled).
+         */
+        SessionModeSetter mode;
+
+        /**
+         * Setting this field will update the session’s actual duration, equivalent
+         * to calling reportActualWorkDuration([workDuration]). Only one duration
+         * can be passed at a time; this API expects durations to be reported
+         * immediately each frame, since the overhead of this call is much lower.
+         */
+        WorkDurationFixedV1 workDuration;
+
+        /**
+         * This structure is used to fit both the mode and the state within one
+         * entry in the union.
+         */
+        @FixedSize
+        @VintfStability
+        parcelable SessionModeSetter {
+            SessionMode modeInt;
+            boolean enabled;
+        }
+    }
+}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index ee8e5a3..e25714f 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -17,8 +17,11 @@
 package android.hardware.power;
 
 import android.hardware.power.Boost;
+import android.hardware.power.ChannelConfig;
 import android.hardware.power.IPowerHintSession;
 import android.hardware.power.Mode;
+import android.hardware.power.SessionConfig;
+import android.hardware.power.SessionTag;
 
 @VintfStability
 interface IPower {
@@ -103,4 +106,42 @@
      *         EX_UNSUPPORTED_OPERATION if hint session is not supported.
      */
     long getHintSessionPreferredRate();
+
+    /**
+     * A version of createHintSession that returns an additional bundle of session
+     * data, useful to help the session immediately communicate via an FMQ channel
+     * for more efficient updates.
+     *
+     * @return  the new session if it is supported on this device, otherwise return
+     *          with EX_UNSUPPORTED_OPERATION error if hint session is not
+     *          supported on this device.
+     * @param   tgid The TGID to be associated with this session.
+     * @param   uid The UID to be associated with this session.
+     * @param   threadIds The list of threads to be associated with this session.
+     * @param   durationNanos The desired duration in nanoseconds for this session.
+     * @param   config Extra session metadata to be returned to the caller.
+     */
+    IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds,
+            in long durationNanos, in SessionTag tag, out SessionConfig config);
+
+    /**
+     * Used to get an FMQ channel, per-process. The channel should be unique to
+     * that process, and should return the same ChannelConfig if called multiple
+     * times from that same process.
+     *
+     * @return  the channel config if hint sessions are supported on this device,
+     *          otherwise return with EX_UNSUPPORTED_OPERATION.
+     * @param   tgid The TGID to be associated with this channel.
+     * @param   uid The UID to be associated with this channel.
+     */
+    ChannelConfig getSessionChannel(in int tgid, in int uid);
+
+    /**
+     * Used to close a channel once it is no longer needed by a process, or that
+     * process dies.
+     *
+     * @param   tgid The TGID to be associated with this channel.
+     * @param   uid The UID to be associated with this channel.
+     */
+    oneway void closeSessionChannel(in int tgid, in int uid);
 }
diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl
index 62263c8..9dd251f 100644
--- a/power/aidl/android/hardware/power/IPowerHintSession.aidl
+++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.power;
 
+import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionHint;
 import android.hardware.power.SessionMode;
 import android.hardware.power.WorkDuration;
@@ -91,4 +92,11 @@
      * @param enabled True to enable the mode, false to disable it
      */
     oneway void setMode(SessionMode type, boolean enabled);
+
+    /**
+     * This method provides direct access to a session's config data.
+     *
+     * @return  the config data for this session
+     */
+    SessionConfig getSessionConfig();
 }
diff --git a/power/aidl/android/hardware/power/SessionConfig.aidl b/power/aidl/android/hardware/power/SessionConfig.aidl
new file mode 100644
index 0000000..93dc9a2
--- /dev/null
+++ b/power/aidl/android/hardware/power/SessionConfig.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+/**
+ * Additional session to be passed to the hint session during creation, or acquired
+ * after creation from the session directly.
+ */
+@VintfStability
+parcelable SessionConfig {
+    /**
+     * The session's unique ID, used to identify the session for debugging and
+     * for multiplexing on the per-process FMQ channel.
+     */
+    long id;
+}
diff --git a/power/aidl/android/hardware/power/SessionTag.aidl b/power/aidl/android/hardware/power/SessionTag.aidl
new file mode 100644
index 0000000..c1d48e4
--- /dev/null
+++ b/power/aidl/android/hardware/power/SessionTag.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@Backing(type="int")
+enum SessionTag {
+    /**
+     * This tag is used to mark uncategorized hint sessions.
+     */
+    OTHER,
+
+    /**
+     * This tag is used to mark the SurfaceFlinger hint session.
+     */
+    SURFACEFLINGER,
+
+    /**
+     * This tag is used to mark HWUI hint sessions.
+     */
+    HWUI,
+
+    /**
+     * This tag is used to mark Game hint sessions.
+     */
+    GAME,
+}
diff --git a/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl b/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl
new file mode 100644
index 0000000..2d202ff
--- /dev/null
+++ b/power/aidl/android/hardware/power/WorkDurationFixedV1.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@FixedSize
+@VintfStability
+parcelable WorkDurationFixedV1 {
+    /**
+     * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the duration
+     * sample was measured.
+     */
+    long timeStampNanos;
+
+    /**
+     * Total work duration in nanoseconds.
+     */
+    long durationNanos;
+
+    /**
+     * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the work starts.
+     * The work period start timestamp could be zero if the call is from
+     * the legacy SDK/NDK reportActualWorkDuration API.
+     */
+    long workPeriodStartTimestampNanos;
+
+    /**
+     * CPU work duration in nanoseconds.
+     * The CPU work duration could be the same as the total work duration if
+     * the call is from the legacy SDK/NDK reportActualWorkDuration API.
+     */
+    long cpuDurationNanos;
+
+    /**
+     * GPU work duration in nanoseconds.
+     * The GPU work duration could be zero if the call is from the legacy
+     * SDK/NDK reportActualWorkDuration API.
+     */
+    long gpuDurationNanos;
+}
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index e3af179..b4ccc7d 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -29,8 +29,12 @@
     vintf_fragments: [":android.hardware.power.xml"],
     vendor: true,
     shared_libs: [
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
         "libbase",
         "libbinder_ndk",
+        "libcutils",
+        "libfmq",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 8fe370c..8f15663 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -18,6 +18,8 @@
 #include "PowerHintSession.h"
 
 #include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
 
 namespace aidl {
 namespace android {
@@ -27,6 +29,10 @@
 namespace example {
 
 using namespace std::chrono_literals;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::hardware::power::ChannelMessage;
+using ::android::AidlMessageQueue;
 
 using ndk::ScopedAStatus;
 
@@ -70,6 +76,27 @@
     return ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Power::createHintSessionWithConfig(
+        int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
+        SessionTag, SessionConfig* config, std::shared_ptr<IPowerHintSession>* _aidl_return) {
+    auto out = createHintSession(tgid, uid, threadIds, durationNanos, _aidl_return);
+    static_cast<PowerHintSession*>(_aidl_return->get())->getSessionConfig(config);
+    return out;
+}
+
+ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) {
+    static AidlMessageQueue<ChannelMessage, SynchronizedReadWrite> stubQueue{1, true};
+    _aidl_return->channelDescriptor = stubQueue.dupeDesc();
+    _aidl_return->readFlagBitmask = 0;
+    _aidl_return->writeFlagBitmask = 0;
+    _aidl_return->eventFlagDescriptor = std::nullopt;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::closeSessionChannel(int32_t, int32_t) {
+    return ndk::ScopedAStatus::ok();
+}
+
 ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
     *outNanoseconds = std::chrono::nanoseconds(1ms).count();
     return ScopedAStatus::ok();
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index 7f8405e..baabaa7 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <aidl/android/hardware/power/BnPower.h>
+#include "aidl/android/hardware/power/SessionTag.h"
 
 namespace aidl {
 namespace android {
@@ -35,7 +36,14 @@
                                          const std::vector<int32_t>& threadIds,
                                          int64_t durationNanos,
                                          std::shared_ptr<IPowerHintSession>* _aidl_return) override;
+    ndk::ScopedAStatus createHintSessionWithConfig(
+            int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds, int64_t durationNanos,
+            SessionTag tag, SessionConfig* config,
+            std::shared_ptr<IPowerHintSession>* _aidl_return) override;
     ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override;
+    ndk::ScopedAStatus getSessionChannel(int32_t tgid, int32_t uid,
+                                         ChannelConfig* _aidl_return) override;
+    ndk::ScopedAStatus closeSessionChannel(int32_t tgid, int32_t uid) override;
 
   private:
     std::vector<std::shared_ptr<IPowerHintSession>> mPowerHintSessions;
diff --git a/power/aidl/default/PowerHintSession.cpp b/power/aidl/default/PowerHintSession.cpp
index 452e435..847a42e 100644
--- a/power/aidl/default/PowerHintSession.cpp
+++ b/power/aidl/default/PowerHintSession.cpp
@@ -17,6 +17,7 @@
 #include "PowerHintSession.h"
 
 #include <android-base/logging.h>
+#include "android/binder_auto_utils.h"
 
 namespace aidl::android::hardware::power::impl::example {
 
@@ -63,4 +64,9 @@
     return ScopedAStatus::ok();
 }
 
+ScopedAStatus PowerHintSession::getSessionConfig(SessionConfig* _aidl_return) {
+    _aidl_return->id = 1;
+    return ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/default/PowerHintSession.h b/power/aidl/default/PowerHintSession.h
index b488bf1..2ed5588 100644
--- a/power/aidl/default/PowerHintSession.h
+++ b/power/aidl/default/PowerHintSession.h
@@ -35,6 +35,7 @@
     ndk::ScopedAStatus sendHint(SessionHint hint) override;
     ndk::ScopedAStatus setThreads(const std::vector<int32_t>& threadIds) override;
     ndk::ScopedAStatus setMode(SessionMode mode, bool enabled) override;
+    ndk::ScopedAStatus getSessionConfig(SessionConfig* _aidl_return) override;
 };
 
 }  // namespace aidl::android::hardware::power::impl::example
diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp
index eb98b8b..c9285f4 100644
--- a/power/aidl/vts/Android.bp
+++ b/power/aidl/vts/Android.bp
@@ -31,6 +31,11 @@
     srcs: ["VtsHalPowerTargetTest.cpp"],
     shared_libs: [
         "libbinder_ndk",
+        "libfmq",
+    ],
+    static_libs: [
+        "android.hardware.common.fmq-V1-ndk",
+        "android.hardware.common-V2-ndk",
     ],
     test_suites: [
         "general-tests",
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 96995a0..11d44b8 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -24,12 +24,22 @@
 #include <android/binder_process.h>
 #include <android/binder_status.h>
 
+#include <fmq/AidlMessageQueue.h>
+#include <fmq/EventFlag.h>
+
 #include <unistd.h>
+#include <cstdint>
+#include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h"
+#include "fmq/EventFlag.h"
 
 namespace aidl::android::hardware::power {
 namespace {
 
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
 using android::hardware::power::Boost;
+using android::hardware::power::ChannelConfig;
+using android::hardware::power::ChannelMessage;
 using android::hardware::power::IPower;
 using android::hardware::power::IPowerHintSession;
 using android::hardware::power::Mode;
@@ -37,6 +47,8 @@
 using android::hardware::power::SessionMode;
 using android::hardware::power::WorkDuration;
 
+using SessionMessageQueue = AidlMessageQueue<ChannelMessage, SynchronizedReadWrite>;
+
 const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};
 
 const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
@@ -190,6 +202,31 @@
     ASSERT_GE(rate, 1000000);
 }
 
+TEST_P(PowerAidl, createHintSessionWithConfig) {
+    if (mServiceVersion < 5) {
+        GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+    }
+    std::shared_ptr<IPowerHintSession> session;
+    SessionConfig config;
+
+    auto status = power->createHintSessionWithConfig(getpid(), getuid(), kSelfTids, 16666666L,
+                                                     SessionTag::OTHER, &config, &session);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_NE(nullptr, session);
+}
+
+TEST_P(PowerAidl, getAndCloseSessionChannel) {
+    if (mServiceVersion < 5) {
+        GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+    }
+    ChannelConfig config;
+    auto status = power->getSessionChannel(getpid(), getuid(), &config);
+    ASSERT_TRUE(status.isOk());
+    auto messageQueue = std::make_shared<SessionMessageQueue>(config.channelDescriptor, true);
+    ASSERT_TRUE(messageQueue->isValid());
+    ASSERT_TRUE(power->closeSessionChannel(getpid(), getuid()).isOk());
+}
+
 TEST_P(HintSessionAidl, createAndCloseHintSession) {
     ASSERT_TRUE(mSession->pause().isOk());
     ASSERT_TRUE(mSession->resume().isOk());
@@ -252,6 +289,14 @@
     }
 }
 
+TEST_P(HintSessionAidl, getSessionConfig) {
+    if (mServiceVersion < 5) {
+        GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
+    }
+    SessionConfig config;
+    ASSERT_TRUE(mSession->getSessionConfig(&config).isOk());
+}
+
 // FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
 // or later
 TEST_P(PowerAidl, hasFixedPerformance) {