From caac147d01566b75c3a8ec0f5d4e8ef577f6ba4e Mon Sep 17 00:00:00 2001 From: Matt Buckley Date: Tue, 12 Dec 2023 03:55:50 +0000 Subject: [PATCH] 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 --- power/aidl/Android.bp | 9 ++ .../android/hardware/power/ChannelConfig.aidl | 41 ++++++++ .../hardware/power/ChannelMessage.aidl | 52 ++++++++++ .../android/hardware/power/IPower.aidl | 3 + .../hardware/power/IPowerHintSession.aidl | 1 + .../android/hardware/power/SessionConfig.aidl | 38 ++++++++ .../android/hardware/power/SessionTag.aidl | 41 ++++++++ .../hardware/power/WorkDurationFixedV1.aidl | 42 +++++++++ .../android/hardware/power/ChannelConfig.aidl | 52 ++++++++++ .../hardware/power/ChannelMessage.aidl | 94 +++++++++++++++++++ power/aidl/android/hardware/power/IPower.aidl | 41 ++++++++ .../hardware/power/IPowerHintSession.aidl | 8 ++ .../android/hardware/power/SessionConfig.aidl | 30 ++++++ .../android/hardware/power/SessionTag.aidl | 41 ++++++++ .../hardware/power/WorkDurationFixedV1.aidl | 53 +++++++++++ power/aidl/default/Android.bp | 4 + power/aidl/default/Power.cpp | 27 ++++++ power/aidl/default/Power.h | 8 ++ power/aidl/default/PowerHintSession.cpp | 6 ++ power/aidl/default/PowerHintSession.h | 1 + power/aidl/vts/Android.bp | 5 + power/aidl/vts/VtsHalPowerTargetTest.cpp | 45 +++++++++ 22 files changed, 642 insertions(+) create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelConfig.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/ChannelMessage.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionConfig.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDurationFixedV1.aidl create mode 100644 power/aidl/android/hardware/power/ChannelConfig.aidl create mode 100644 power/aidl/android/hardware/power/ChannelMessage.aidl create mode 100644 power/aidl/android/hardware/power/SessionConfig.aidl create mode 100644 power/aidl/android/hardware/power/SessionTag.aidl create mode 100644 power/aidl/android/hardware/power/WorkDurationFixedV1.aidl diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp index 76439265af..8900fb8848 100644 --- a/power/aidl/Android.bp +++ b/power/aidl/Android.bp @@ -28,11 +28,20 @@ aidl_interface { "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 0000000000..d3caca413b --- /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 -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 channelDescriptor; + @nullable android.hardware.common.fmq.MQDescriptor 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 0000000000..25f01c0d91 --- /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 -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 ae03313f11..8acdaf2014 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 @@ interface IPower { 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 6bc663e125..010f815476 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 @@ interface IPowerHintSession { 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 0000000000..b03cfb2db1 --- /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 -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 0000000000..80848a41cb --- /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 -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 0000000000..8cd246d6bf --- /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 -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 0000000000..4da292ed51 --- /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 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 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 0000000000..4747d90463 --- /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 ee8e5a3a61..e25714fda5 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 @@ interface IPower { * 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 62263c8aa9..9dd251fba9 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 @@ interface IPowerHintSession { * @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 0000000000..93dc9a278e --- /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 0000000000..c1d48e4318 --- /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 0000000000..2d202ff198 --- /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 e3af179ea9..b4ccc7db6b 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/Android.bp @@ -29,8 +29,12 @@ cc_binary { 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 8fe370c3e4..8f15663db9 100644 --- a/power/aidl/default/Power.cpp +++ b/power/aidl/default/Power.cpp @@ -18,6 +18,8 @@ #include "PowerHintSession.h" #include +#include +#include namespace aidl { namespace android { @@ -27,6 +29,10 @@ namespace impl { 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 @@ ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector& threadIds, int64_t durationNanos, + SessionTag, SessionConfig* config, std::shared_ptr* _aidl_return) { + auto out = createHintSession(tgid, uid, threadIds, durationNanos, _aidl_return); + static_cast(_aidl_return->get())->getSessionConfig(config); + return out; +} + +ndk::ScopedAStatus Power::getSessionChannel(int32_t, int32_t, ChannelConfig* _aidl_return) { + static AidlMessageQueue 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 7f8405eff3..baabaa7271 100644 --- a/power/aidl/default/Power.h +++ b/power/aidl/default/Power.h @@ -17,6 +17,7 @@ #pragma once #include +#include "aidl/android/hardware/power/SessionTag.h" namespace aidl { namespace android { @@ -35,7 +36,14 @@ class Power : public BnPower { const std::vector& threadIds, int64_t durationNanos, std::shared_ptr* _aidl_return) override; + ndk::ScopedAStatus createHintSessionWithConfig( + int32_t tgid, int32_t uid, const std::vector& threadIds, int64_t durationNanos, + SessionTag tag, SessionConfig* config, + std::shared_ptr* _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> mPowerHintSessions; diff --git a/power/aidl/default/PowerHintSession.cpp b/power/aidl/default/PowerHintSession.cpp index 452e435c29..847a42e7c3 100644 --- a/power/aidl/default/PowerHintSession.cpp +++ b/power/aidl/default/PowerHintSession.cpp @@ -17,6 +17,7 @@ #include "PowerHintSession.h" #include +#include "android/binder_auto_utils.h" namespace aidl::android::hardware::power::impl::example { @@ -63,4 +64,9 @@ ScopedAStatus PowerHintSession::setMode(SessionMode /* mode */, bool /* enabled 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 b488bf108e..2ed55885f4 100644 --- a/power/aidl/default/PowerHintSession.h +++ b/power/aidl/default/PowerHintSession.h @@ -35,6 +35,7 @@ class PowerHintSession : public BnPowerHintSession { ndk::ScopedAStatus sendHint(SessionHint hint) override; ndk::ScopedAStatus setThreads(const std::vector& 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 eb98b8b5bf..c9285f4eaa 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/Android.bp @@ -31,6 +31,11 @@ cc_test { 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 96995a0acc..11d44b8ab5 100644 --- a/power/aidl/vts/VtsHalPowerTargetTest.cpp +++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp @@ -24,12 +24,22 @@ #include #include +#include +#include + #include +#include +#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::SessionHint; using android::hardware::power::SessionMode; using android::hardware::power::WorkDuration; +using SessionMessageQueue = AidlMessageQueue; + const std::vector kBoosts{ndk::enum_range().begin(), ndk::enum_range().end()}; const std::vector kModes{ndk::enum_range().begin(), ndk::enum_range().end()}; @@ -190,6 +202,31 @@ TEST_P(PowerAidl, getHintSessionPreferredRate) { ASSERT_GE(rate, 1000000); } +TEST_P(PowerAidl, createHintSessionWithConfig) { + if (mServiceVersion < 5) { + GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond."; + } + std::shared_ptr 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(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, setSessionMode) { } } +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) {