Skip to content

Conversation

@rayavanindra
Copy link

@rayavanindra rayavanindra commented Jul 21, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a power management service with AIDL integration for better performance and efficiency.
    • Added dynamic performance controls based on user interactions and application needs.
    • Implemented session management for power hints to optimize power usage.
    • Added new methods for managing power modes and boosts.
  • Bug Fixes

    • Improved stability and responsiveness of power management with refined error handling.
  • Documentation

    • Added manifest and configuration files for power HAL service, enhancing system integration.
  • Chores

    • Created necessary files and classes to support the new power management functionalities.

bgcngm and others added 30 commits July 21, 2024 00:19
Based on implementation from hardware/google/pixel as of commit 0338a0e.

Change-Id: I3df57bd3e8298141272add55c911fb5eece9aebe
Bug: 147840817
Test: boot and check power hint
Change-Id: I9c0c98e76ef4b5f4756f63ed5122efc366737869
Bug: 151896829
Test: boot flame
Change-Id: Ie951008cabe2a5680fbc546a21bdc9a428864ef9
Bug: 147840817
Test: boot
Change-Id: Ic1d6e04109683b999bb99484930e95dc9813fc59
Bug: 152811907
Test: Build
Change-Id: I6848e929d8a26b540fcee9145376b896c3cd9799
Because perfmgr is a vendor process, it cannot adjust system priority
directly.

Bug: 162791243

Test: build and using emul temp/running burn8 to verify it
Change-Id: I55e49cb7d0b2d4c0e42dff8398b5d42c6546cafa
Bug: 162791243
Bug: 72471476
Test: build and using emul temp/running burn8 to verify it
Change-Id: I5ca475be8b73b940e4858634595a7918ae92f6ef
Change-Id: Iac0e65a16f660583d3400a35622113d35d8d1d27
To workaround b/141025174, adding support for devices without display
idle signals. Also added a property to override idle display function.

Besides the idle signal support, this CL also makes touch boost duration
tunable through several new vendor properties. It also named display
idle monitor thread and cleans out the obsolete HIDL Power HAL
implementation.

Bug: 168080943
Bug: 169065024
Bug: 171494137
Test: Boot and trace
Change-Id: I76067d10958654d539624ec4cac8f346103e67bc
Test: Build
Bug: 169065024
Signed-off-by: Wei Wang <[email protected]>
Change-Id: I3cef3aff4bb2394571a3de13e535283722c308ed
Test: build
Bug: 173222103
Signed-off-by: Wei Wang <[email protected]>
Change-Id: I14e7e0aa349e446f6889cbfc9a914f5314438e6b
Bug: 150578172
Test: m
Change-Id: I4a9bf218b92252403e9ebbe8f89b10ee1899283f
Adapted from PoC from ag/13100800

Added more ATRACE for further tuning and debug

Test: APPPID=$(adb shell pidof com.prefabulated.touchlatency); watch -n
      1 adb shell grep uclamp /proc/${APPPID}/sched
Test: atest VtsHalPowerTargetTest
Bug: 177492680
Change-Id: I6bfd61b21dc1cde04f6ba9ae8d3533cd263ad814
Signed-off-by: Wei Wang <[email protected]>
Add bunch of TODO for team as well.

Test: build
Bug: 177492680
Bug: 185368789
Signed-off-by: Wei Wang <[email protected]>
Change-Id: Ic1d5ecea10a60b23343866cd62519fda37bd6ec5
The patch includes:
1. Move from folder adpf to aidl.
2. Add PowerSessionManager class to maintain hint status.
   And PowerHintMointor looper thread for monitoring or updating
   PowerHintSession status.
3. Use PID algorithm to replace the step-wise alogrithm for cpu resource
   control.

Test: build, boot to home, trace analysis
Bug: 177493042
Change-Id: Ib7d3f414225b18954350341ca22b7be87a6202e7
Fixes: ag/14313466
Bug: 177493042
Bug: 191163855
Test: Build
Change-Id: I94812997a8214b77a2e1d0bcf90ef62205c5adf6
Signed-off-by: Wei Wang <[email protected]>
Cache active state and reduce log spam
Add value tracing into libperfmgr
Use adaptive stale timeout based on rate limit

Bug: 191331719
Bug: 191296994
Bug: 177493042
Test: boot
Signed-off-by: Wei Wang <[email protected]>
Change-Id: I1c1484c9277209bf68bd287ceae83e2b37684c62
Also change default window setting to 0

Bug: 191409203
Test: Build
Signed-off-by: Wei Wang <[email protected]>
Change-Id: Ieadf50a64e795d9942373c411189adf9daaee779
clean up ADPF trace points and use vendor.powerhal.adpf.uclamp.boost_cap
instead of vendor.powerhal.adpf.uclamp.cap_ratio.

Bug: 191551452
Test: build
Change-Id: I457710b1bd9a7adbb55749d7bb915c736dde2751
Bug: 191480755
Test: Build
Signed-off-by: Wei Wang <[email protected]>
Change-Id: Id559796ee4a423410148b8c2df0524909658af82
When seesion is created, set uclamp to boost CPU for top-app.

Bug: 192143316
Test: Build and run UiBenchSlowNestedRecyclerViewInitialFlingMicrobenchmark test
Change-Id: I748037019fae439ab1863a5ed21aa98b9d26e0dc
"GPU completion" task inherits a high uclamp value from RenderThread.
But it's not in the ADPF thread list, so it remains a high uclamp value.
Use SetTaskProfiles("ResetUclampGrp") and
SetTaskProfiles("NoResetUclampGrp") to manage the uclamp_fork_reset for
tasks.

Bug: 191973176
Bug: 192149875
Test: vendor/google_testing/pts/tests/common/utils/perf/run_pts/jank_test.sh
Test: adb shell cat /proc/vendor_sched/dump_task
Change-Id: I6aed171e88c0a6db5f762e7c791344bb3f4b7a90
To get rid of error logs, avoid to call close() twice.

07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to
look up tid:2585 in TidRefCountMap
07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to
look up tid:2586 in TidRefCountMap
07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to
look up tid:2031 in TidRefCountMap
07-29 17:20:35.341 E powerhal-libperfmgr: Unexpected Error! Failed to
look up tid:2585 in TidRefCountMap

Bug: 194775170
Test: build and check log.
Change-Id: I91adf907b837382f68935b9054e19465a499049c
Tuning the PID control loop as the below:
ILowLimit: -512 -> -120
kPOver: 2->5
kPunder: 2->3
kDOver: 1->5
kDUnder: 0->0

Bug: 193165816
Test: cuj/youtuble, cuj/facebook, PtsUiBench
Change-Id: Icc1a9a8d04004f60e47cabb7c4131ea67585be53
Test: systrace
Bug: 199776250
Change-Id: I9bb4d5a50faa93e7bc638ef723bdc2662fb63b24
1. set uclamp.min high to 384 (from 512)
2. set uclamp.min low to 2 (from 0)
3. set kPo to 2 (from 5)
4. set kPu to 1 (from 3)
5. instead of the previous boost value, use I Error-Integral as the base
   of boost value.
6. add more traces (wakeup, overtime)

Bug: 198708191
Bug: 197586898
Bug: 197540375
Test: build and check trace
      adb shell perfetto -o \
      /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched \
      freq idle am wm gfx view power hal
Change-Id: I35484322a84c2ab19f3024cf6634c1818ba570b0
Bug: 196192645
Test: Manual
Change-Id: Ibdbb8f47a16032ce3249aa667fa0c11e7869748f
Add a bool property `vendor.powerhal.config.debug`.
Power HAL would use `/data/vendor/etc/powerhint.json` when vendor.powerhal.config.debug = true.

Bug: 218872105
Bug: 206061061
Test: adb wait-for-device root; adb shell mkdir -p /data/vendor/etc/;
      adb push powerhint_mod.json /data/vendor/etc/powerhint.json
Test: adb shell setprop vendor.powerhal.config.debug true && \
      adb shell getprop vendor.powerhal.config.debug && \
      adb shell stop vendor.power-hal-aidl && \
      adb shell start vendor.power-hal-aidl && adb shell stop && adb shell start
Test: adb pull /data/local.prop ; vim local.prop
      + vendor.powerhal.config.debug=true
Test: adb wait-for-device root && adb shell perfetto -o \
      /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched freq \
      idle am wm gfx view power hal && \
      adb pull /data/misc/perfetto-traces/trace_file.perfetto-trace trace_profile_debug.pftrace
Change-Id: Ibaf5df280b989a8268efce1e3ab9a3f1e5510800
An init trigger would restart powerhal as early as the property was
loaded and it is hopefully early than any clients would try to connect.

Also remove the obsolete restart hook with audio.

Bug: 218872105
Test: boot
Signed-off-by: Wei Wang <[email protected]>
Change-Id: Ib55897f65709a963016b729f213718aae5af8e8c
1. Clean all messages before add new.
2. Insteading of using `this`, use the unique mStaleHandler sp so Looper
   can hold the sp to keep the instance alive until the last message
   done.

Test: Manual Test
Bug: 219965773
Change-Id: Ic039146f0b966c1f27d86b121d4b72b75ff360e5
weivincewang and others added 28 commits July 21, 2024 00:19
For DISPLAY_UPDATE_IMMINENT wakeup signal, non-stale
session's timer should be also extended. This resolves
the performance issue caused those sessions to go stale    
prematurely.

Bug: 241621485
Test: Build
Signed-off-by: Wei Wang <[email protected]>
Change-Id: I06330e064060248bb556ae35e0cb8fd302cef231
…ble boost.

Optimize boost:
A more efficient way is to trigger the wakeup boost through mTidSessionListMap, so the time
   complexity reduce from O(n^3) to O(n^2).

The original code path:
  PSM:wakeSessions() contains a loop that is O(n),
  inside the loop, it calls to PHS::wakeup() which call to
  PSM::setUclampMinLocked(), and
  PSM::setUclampMinLocked() contains two loops O(n^2)

The new code path:
  PSM::wakeSessions() directly checks all the ADPF tasks O(n) and
  get the wakeup boost value O(n), then directly set the uclamp.min
  The time complexity lower to O(n^2).

Fix unstable boost:
The original flow is to find max boost and wake it up from stale state
one by one. But the previous woken ones would not be counted when the later ones finding their max boost value.
The new flow boost all the tasks first, then wake up all those sessions.

Bug: 235510337
Test: Manually playing UIBench -> Transitions -> ActivityTransition
Change-Id: I995673b74401e198eb72188134ba1ebc134f971c
The main problem is the timer thread could be woken after the session
was destroyed. We did have a closed flag which was set in destructor and the flag would be checked before handleMessage accessing the session
instance. To fix the problem, the operations of flag checking and session instance accessing should be guarded by the lock.

Bug: 236674672
Test: manual test
Change-Id: I49a18efbc135b1bc070b101038a8a0bcc6e19fec
(cherry picked from commit 5c75978f530b27bd976d8695ed79acd336c24776)
Merged-In: I49a18efbc135b1bc070b101038a8a0bcc6e19fec
Send a hint only when the system can support the hint.

Bug: 243025173
Test: PtsUiBench & CUJ
Change-Id: If56d0c22f8dd61f5fe27ba79f08f2963269abe41
Merged-In: If56d0c22f8dd61f5fe27ba79f08f2963269abe41
To send ADPF_FIRST_FRAME hint when reportWorkDurations was called first
time after stale state.

Bug: 243025173
Test: PtsUiBench & CUJ
Change-Id: I4377b1f549646bcf44bdf26b2657b7bc0646f9a4
Merged-In: I4377b1f549646bcf44bdf26b2657b7bc0646f9a4
The ndk_platform backend will soon be deprecated because the ndk backend
can serve the same purpose. This is to eliminate the confusion about
having two variants (ndk and ndk_platform) for the same ndk backend.

Bug: 161456198
Test: m
Change-Id: I14a1c57bd06f1f2aa52491f779c7030d4de03547
… ADPF

Bug: 201769701
Test: atest android.gamemanager.cts.GameManagerTest
Change-Id: I268ca9cc8e2f212bdb9c8bb1c890e7a845170ec6
Bug: 256515601
Test: build
Change-Id: I9b63c6ee3decaa4c70f38bcc66a0e9e1de464ad6
Bug: 256515601
Test: build
Change-Id: Ia7f80c838961b837733c457b189f16c6433cf3c3
Reset traced hint value to -1 on reportActualWorkDuration or stale
timeout, and rewrite existing tracing for readability.

Bug: b/243973548
Test: manual
Change-Id: I135ec5f8971a9902d880e4089b0df746f5b917e2
…anager

Currently, all sessions get boosted any time DISPLAY_UPDATE_IMMINENT is
sent from SurfaceFlinger which can lead to large, unnecessary boosts.
This patch aims to change that by removing the wakeup behavior, relying
instead on sessions to boost themselves with new load change hints.

 * Remove wakeup() from PowerHintSession
 * Remove wakeSessions from PowerSessionManager
 * Remove related timers and message handlers
 * Remove DISPLAY_UPDATE_IMMINENT behavior entirely

Test: manual
Bug: b/260136431
Change-Id: I4610edfefe8fcbef7d4cdbf5768830a9392a54f7
Have pixel PowerHintSessions implement the new sendHint API to provide
load change hints, allowing hint sessions to rapidly wake up and respond
to sudden changes in workload.

Bug: b/243973548
Test: manual
Change-Id: Ic10a3cee2b88f2bbbf6c74dd1bbad45859145192
…ng tracing

Reset traced hint value to -1 on reportActualWorkDuration or stale
timeout, and rewrite existing tracing for readability.

Bug: b/243973548
Test: manual
Original-Change-Id: I135ec5f8971a9902d880e4089b0df746f5b917e2
Change-Id: I9c622ca8d1fdada5a0cda253ebdbfd42f170d184
…ange hint

Bug: b/243973548
Test: manual
Change-Id: I101e7d9b9d5e6f74c3f3000508314173bed14c9c
Implement IPowerHintSession.setThreads, when threads are updated,
remove all previous threads and readd new threads, set the boost to
initial state.

Minor: Update IPower version to 4.

Bug: b/244216750
Bug: b/257217984
Test: manual
Change-Id: I29e2574d3a107a3e75bf27a4528635e3eedc2d14
Give the first frame after a load change hint an extra boost for
CPU_LOAD_UP and CPU_LOAD_RESET, as it tends to be much more expensive
than the subsequent frames.

Bug: b/243973548
Test: manual
Change-Id: I78942beefeb836862fb65f8fe1a036dd26a44937
Currently, load hint signals boost the first frame but rely on frames
reporting an actual duration to end that boost. This change adds a
secondary timer to provide a maximum boost time based on the target,
in case the session fails to report an actual duration or gets rate
limited.

This patch also refactors the existing timer into a generic superclass
to make sharing timer logic easier.

Bug: 261130508
Test: manual
Change-Id: Icc7fbaed0cb764b6960a8f92a2b6505c7a8583dc
Current reset hint is too aggressive to turn off and uses arbitrary
scaling. This patch seeks to fix existing issues by changing how the
reset hint timeout is calculated.

Bug: 266266524
Bug: 266259814
Test: manual
Change-Id: Ic458ccdd0efeea36ce273681f4ff842d03f9ad7e
Currently the boost timer resets the stale timer when it turns off.
That's less than ideal, but this should fix it.

This also adds code to prevent multiple sequential boosts from re-using
uclamp.min values when calculating what to return to once the boost ends

Bug: 267385642
Bug: 267391322
Test: manual
Change-Id: I70d835f4add242c10788aa893fb2f49774e1a538
Increasingly, cpu_load_up exists as a tool to boost stray expensive
frames rather than to increase the PID setpoint, so this change reflects
that and seeks to prevent power regressions in its use towards this goal

Bug: 261130508
Test: manual
Change-Id: I6608f92decbdfc59d92b4e5716a75b323c1d2c3e
mTidSessionListMap alone can be used to check the ref count.

Bug: b/268744922
Test: n/a
Change-Id: Ic7a3aa32560790683e402253e9e04eadb288e1f7
Set the profile on resume/pause

Bug: 245675204
Bug: 275687673
Test: adb shell dumpsys android.hardware.power.IPower/default
Change-Id: Icadf526a2f262e77d7adb2184f61b3ccba44c601
Replace current init behavior with a reset hint. This makes sense,
because creating a session is implicitly a "load reset" plus HWUI may
not always send a reset hint after its background refactor. This will
also reduce first-frame boost latency for new sessions.

Bug: 279505058
Test: manual
Change-Id: I5bdeedecbd4e0afb7d777be332e5dd9fb386e1ac
Give the first frame minimum mif freq to avoid the situation that
mif at lower level but memlat can't reflect the loading in time.

Bug: 259275437
Bug: 263383561
Test: manual

Original-Change-Id: I1dbcc23fa4a7bc2e3daf05b7cc0489a1ac5953d5
Change-Id: I2f34ba6111027832cf0e544ebc288116855c47cb
Signed-off-by: Luke Chang <[email protected]>
Send a hint only when the system can support the hint.

Bug: 243025173
Test: PtsUiBench & CUJ
Original-Change-Id: If56d0c22f8dd61f5fe27ba79f08f2963269abe41
Change-Id: I2c190ac357aa8c5b5da52e3e1566f4f62c388ba6
… update

If thread is detected as dead while setting the uclamp min, it currently
sends warning log. This caused log spamming issue. Change it to verbose
log first, then consider long term solution in master branch.

Bug: 296159697
Test: Manual
Change-Id: Ia8ea632be75a431ce0f9faa4c3792635f540be16
Bug: 296159697
Test: Manual
Change-Id: Idb74d12fd0d1028514382a4e09116b506b5ec176
* Some devices may want to implement custom hooks

Change-Id: Icb2d66471ec649a69b1e69849fd86282775052cb
@coderabbitai
Copy link

coderabbitai bot commented Jul 21, 2024

Walkthrough

The changes introduce a comprehensive power management framework in the LineageOS Android project. New classes and configurations enhance the hardware abstraction layer (HAL) for power services, allowing for dynamic performance tuning based on user interaction and system states. The structure facilitates better management of power modes, hints, and sessions, optimizing resource usage while ensuring responsiveness and efficiency in device performance.

Changes

Files Change Summary
power-libperfmgr/Android.bp Introduced build configuration for android.hardware.power-service.lineage-libperfmgr and libperfmgr-ext. Defined binary and static library properties, including source files and dependencies.
power-libperfmgr/aidl/InteractionHandler.* Added InteractionHandler class to manage performance locks based on user interactions, implementing a state machine for dynamic control.
power-libperfmgr/aidl/Power.* Implemented Power class for managing power modes and boosts, integrating with HintManager for performance hints.
power-libperfmgr/aidl/PowerExt.* Introduced PowerExt class for extended power management functionalities, allowing device-specific mode and boost manipulation.
power-libperfmgr/aidl/PowerHintSession.* Implemented PowerHintSession for managing CPU performance through power hints with PID control logic.
power-libperfmgr/aidl/PowerSessionManager.* Developed PowerSessionManager to manage power hint sessions and associated threads, ensuring real-time adjustments to power management strategies.
power-libperfmgr/aidl/*.{xml,rc,cpp,h} Added configuration and manifest files for establishing the power HAL service and defining its lifecycle and properties.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant InteractionHandler
    participant Power
    participant PowerSessionManager
    participant HintManager

    User->>InteractionHandler: Request performance lock
    InteractionHandler->>Power: Acquire lock
    Power->>HintManager: Apply performance hint
    PowerSessionManager->>Power: Update session state
    Note right of Power: Dynamic adjustments based on user interactions
Loading

In a world of circuits and light,
A rabbit hops with all its might.
Performance hints and locks anew,
Power dances, swift and true.
With every tweak, the systems hum,
Optimized joy, oh, how we run! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 30

Outside diff range, codebase verification and nitpick comments (9)
power-libperfmgr/aidl/PowerModeExtension.cpp (1)

17-17: Include guard or pragma once.

Consider adding an include guard or #pragma once to prevent potential multiple inclusion issues.

#pragma once
power-libperfmgr/aidl/service.cpp (1)

17-17: Consider using a more descriptive log tag.

The log tag powerhal-libperfmgr is descriptive but could be more specific to the functionality.

power-libperfmgr/aidl/PowerExt.cpp (1)

17-17: Consider using a more descriptive log tag.

The log tag android.hardware.power-service.lineage.ext-libperfmgr is descriptive but could be more specific to the functionality.

power-libperfmgr/aidl/PowerSessionManager.h (5)

Line range hint 116-120:
Add error handling for the session parameter.

Consider adding error handling to check if the session parameter is valid before using it.

if (!session) {
    ALOGW("PowerSessionManager::removePowerSession: session is null");
    return;
}

Line range hint 154-157:
Add error handling for the session parameter.

Consider adding error handling to check if the session parameter is valid before using it.

if (!session) {
    ALOGW("PowerSessionManager::setUclampMin: session is null");
    return;
}

Line range hint 172-189:
Simplify the return type.

Consider returning a boolean value directly instead of using std::optional<bool>.

bool PowerSessionManager::isAnyAppSessionActive() {
    std::lock_guard<std::mutex> guard(mLock);
    for (PowerHintSession *s : mSessions) {
        if (s->isActive() && !s->isTimeout() && s->isAppSession()) {
            return true;
        }
    }
    return false;
}

Line range hint 191-201:
Add logging for debugging purposes.

Consider adding logging to help debug the message handling process.

void PowerSessionManager::handleMessage(const Message &message) {
    ALOGV("PowerSessionManager::handleMessage: received message");
    auto active = isAnyAppSessionActive();
    if (!active.has_value()) {
        return;
    }
    if (active.value()) {
        disableSystemTopAppBoost();
    } else {
        enableSystemTopAppBoost();
    }
}

Line range hint 203-223:
Add error handling for the file descriptor.

Consider adding error handling to check if the file descriptor is valid before using it.

if (fd < 0) {
    ALOGE("PowerSessionManager::dumpToFd: invalid file descriptor");
    return;
}
power-libperfmgr/aidl/InteractionHandler.cpp (1)

145-191: Consider adding more detailed logging.

The Acquire function performs several checks and operations. Adding more detailed logging can help with debugging and understanding the flow of execution.

void InteractionHandler::Acquire(int32_t duration) {
    ATRACE_CALL();

    std::lock_guard<std::mutex> lk(mLock);

    int inputDuration = duration + kDurationOffsetMs;
    int finalDuration;
    if (inputDuration > kMaxDurationMs)
        finalDuration = kMaxDurationMs;
    else if (inputDuration > kMinDurationMs)
        finalDuration = inputDuration;
    else
        finalDuration = kMinDurationMs;

    ALOGV("%s: input: %d, offset: %d, final duration: %d", __func__, duration, kDurationOffsetMs, finalDuration);

    // Fallback to do boost directly
    // 1) override property is set OR
    // 2) InteractionHandler not initialized
    if (!kDisplayIdleSupport || mState == INTERACTION_STATE_UNINITIALIZED) {
        HintManager::GetInstance()->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration));
        return;
    }

    struct timespec cur_timespec;
    clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
    if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
        size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec);
        // don't hint if previous hint's duration covers this hint's duration
        if (elapsed_time <= (mDurationMs - finalDuration)) {
            ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__,
                  static_cast<int>(mDurationMs), static_cast<int>(finalDuration),
                  static_cast<long long>(elapsed_time));
            return;
        }
    }
    mLastTimespec = cur_timespec;
    mDurationMs = finalDuration;

    ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration);

    if (mState == INTERACTION_STATE_WAITING)
        AbortWaitLocked();
    else if (mState == INTERACTION_STATE_IDLE)
        PerfLock();

    mState = INTERACTION_STATE_INTERACTION;
    mCond.notify_one();
}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9f6bf56 and f9a7951.

Files selected for processing (15)
  • power-libperfmgr/Android.bp (1 hunks)
  • power-libperfmgr/aidl/InteractionHandler.cpp (1 hunks)
  • power-libperfmgr/aidl/InteractionHandler.h (1 hunks)
  • power-libperfmgr/aidl/Power.cpp (1 hunks)
  • power-libperfmgr/aidl/Power.h (1 hunks)
  • power-libperfmgr/aidl/PowerExt.cpp (1 hunks)
  • power-libperfmgr/aidl/PowerExt.h (1 hunks)
  • power-libperfmgr/aidl/PowerHintSession.cpp (1 hunks)
  • power-libperfmgr/aidl/PowerHintSession.h (1 hunks)
  • power-libperfmgr/aidl/PowerModeExtension.cpp (1 hunks)
  • power-libperfmgr/aidl/PowerSessionManager.cpp (1 hunks)
  • power-libperfmgr/aidl/PowerSessionManager.h (1 hunks)
  • power-libperfmgr/aidl/android.hardware.power-service.lineage-libperfmgr.rc (1 hunks)
  • power-libperfmgr/aidl/android.hardware.power-service.lineage.xml (1 hunks)
  • power-libperfmgr/aidl/service.cpp (1 hunks)
Additional comments not posted (45)
power-libperfmgr/aidl/android.hardware.power-service.lineage.xml (1)

1-7: Ensure XML manifest correctness.

The XML manifest appears to be correctly formatted and specifies the HAL for android.hardware.power with version 4. Ensure this aligns with the rest of the project requirements and configurations.

power-libperfmgr/aidl/PowerModeExtension.cpp (2)

1-15: Ensure license compliance.

The license header is correctly included and follows the Apache License, Version 2.0. Ensure compliance with the license terms.


19-45: Namespace and function implementations look good.

The namespace structure is well-defined, and the functions isDeviceSpecificModeSupported and setDeviceSpecificMode are correctly stubbed out. Ensure these functions are correctly integrated and implemented as needed.

power-libperfmgr/aidl/android.hardware.power-service.lineage-libperfmgr.rc (6)

1-5: Service definition looks good.

The service definition for vendor.power-hal-aidl is correctly specified with appropriate class, user, group, and priority settings.


7-9: Ensure service starts correctly on late-fs.

The on late-fs trigger to start the service is correctly specified. Ensure this aligns with the overall system initialization sequence.


10-16: Handle framework restart correctly.

The script correctly handles the restart of the powerHAL service when the framework restarts. Ensure this logic is tested thoroughly.


17-25: Ensure property handling for dalvik.vm properties.

The script handles dalvik.vm properties correctly. Ensure these properties are set and restored as intended.


26-29: Debug property handling looks good.

The script correctly handles the restart of the powerHAL service when debug properties are set. Ensure this logic is tested thoroughly.


30-32: Persisted debug property handling looks good.

The script correctly handles persisted debug properties. Ensure this logic is tested thoroughly.

power-libperfmgr/Android.bp (3)

7-12: Namespaces and imports look good.

The soong_namespace section correctly specifies the namespaces and imports.


14-47: Binary configuration looks good.

The cc_binary section correctly specifies the binary configuration, including dependencies, source files, and other settings.


49-58: Static library configuration looks good.

The cc_library_static section correctly specifies the static library configuration, including dependencies and source files.

power-libperfmgr/aidl/PowerExt.h (3)

1-25: File header and includes look good.

The file header contains correct licensing information, and the necessary headers are included.


26-39: Class definition and public methods look good.

The class PowerExt extends BnPowerExt and provides methods for setting and checking power modes and boosts. The methods are correctly defined.


41-42: Private section is correctly defined.

The private section of the class PowerExt is currently empty but correctly defined.

power-libperfmgr/aidl/InteractionHandler.h (4)

1-24: File header and includes look good.

The file header contains correct licensing information, and the necessary headers are included.


32-37: Enum definition looks good.

The enum InteractionState correctly defines various states for interaction management.


39-46: Class definition and public methods look good.

The class InteractionHandler provides methods for initializing, exiting, acquiring, and releasing interactions. The methods are correctly defined.


48-64: Private section looks good.

The private section of the class InteractionHandler contains private methods and member variables for managing interactions. The methods and variables are correctly defined.

power-libperfmgr/aidl/Power.h (3)

1-15: Ensure compliance with the Apache License.

The file includes the Apache License header, which is good practice.


19-25: Ensure all necessary headers are included.

The file includes several headers, which seem appropriate for the functionality.


38-55: Class Power implementation looks good.

The class Power extends BnPower and implements several methods related to power management.

power-libperfmgr/aidl/service.cpp (3)

1-15: Ensure compliance with the Apache License.

The file includes the Apache License header, which is good practice.


19-31: Ensure all necessary headers are included.

The file includes several headers, which seem appropriate for the functionality.


40-83: Main function implementation looks good.

The main function initializes the power HAL service, registers the service, and starts the necessary components.

power-libperfmgr/aidl/PowerExt.cpp (3)

1-15: Ensure compliance with the Apache License.

The file includes the Apache License header, which is good practice.


19-31: Ensure all necessary headers are included.

The file includes several headers, which seem appropriate for the functionality.


33-87: Class PowerExt implementation looks good.

The class PowerExt extends functionality for power management and implements several methods.

power-libperfmgr/aidl/PowerSessionManager.h (2)

100-104: Clarify the purpose of the method.

The method logs the boost and duration but does not perform any action. Clarify if this is intentional or if additional logic is required.


106-108: LGTM!

The method is simple and correctly implemented.

power-libperfmgr/aidl/PowerHintSession.h (1)

84-84: LGTM!

The method is simple and correctly implemented.

power-libperfmgr/aidl/PowerSessionManager.cpp (2)

100-104: Clarify the purpose of the method.

The method logs the boost and duration but does not perform any action. Clarify if this is intentional or if additional logic is required.


106-108: LGTM!

The method is simple and correctly implemented.

power-libperfmgr/aidl/InteractionHandler.cpp (3)

49-50: Ensure the property key is correct.

The property key vendor.powerhal.disp.idle_support is used to determine display idle support. Verify that this key is correct and exists in the system properties.


51-52: Confirm the validity of file paths.

The file paths /sys/class/drm/card0/device/idle_state and /sys/class/graphics/fb0/idle_state are used to check the display idle state. Ensure these paths are correct and accessible on the target devices.


53-60: Verify property keys and default values.

The property keys vendor.powerhal.disp.idle_wait, vendor.powerhal.interaction.min, vendor.powerhal.interaction.max, and vendor.powerhal.interaction.offset are used to configure various parameters. Ensure these keys are correct and the default values are appropriate.

power-libperfmgr/aidl/Power.cpp (5)

129-137: LGTM!

The isModeSupported method correctly checks for mode support.


177-181: LGTM!

The isBoostSupported method correctly checks for boost support.


188-201: LGTM!

The dump method correctly writes the current state to a file descriptor.


204-221: LGTM!

The createHintSession method correctly creates a new power hint session.


224-232: LGTM!

The getHintSessionPreferredRate method correctly retrieves the preferred rate for hint sessions.

power-libperfmgr/aidl/PowerHintSession.cpp (4)

150-152: LGTM!

The traceSessionVal method correctly traces session values.


154-157: LGTM!

The isAppSession method correctly checks if the session is an application session.


159-171: LGTM!

The updateUniveralBoostMode method correctly updates the universal boost mode.


173-179: LGTM!

The tryToSendPowerHint method correctly sends power hints.

* limitations under the License.
*/

#pragma once
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using #ifndef guards instead of #pragma once.

While #pragma once is widely supported, using #ifndef guards can improve portability.

#ifndef AIDL_GOOGLE_HARDWARE_POWER_IMPL_PIXEL_POWER_H
#define AIDL_GOOGLE_HARDWARE_POWER_IMPL_PIXEL_POWER_H

// ... code ...

#endif // AIDL_GOOGLE_HARDWARE_POWER_IMPL_PIXEL_POWER_H

Comment on lines +47 to +48
void updateHintMode(const std::string &mode, bool enabled);
void updateHintBoost(const std::string &boost, int32_t durationMs);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate the mode string.

Consider adding validation for the mode string to ensure it matches expected values.

if (mode.empty()) {
    ALOGW("PowerSessionManager::updateHintMode: mode is empty");
    return;
}

Comment on lines +110 to +114

} // namespace pixel
} // namespace impl
} // namespace power
} // namespace hardware
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for the session parameter.

Consider adding error handling to check if the session parameter is valid before using it.

if (!session) {
    ALOGW("PowerSessionManager::addPowerSession: session is null");
    return;
}

Comment on lines +46 to +56
struct AppHintDesc {
AppHintDesc(int32_t tgid, int32_t uid, std::vector<int32_t> threadIds)
: tgid(tgid),
uid(uid),
threadIds(std::move(threadIds)),
duration(0LL),
current_min(0),
is_active(true),
update_count(0),
integral_error(0),
previous_error(0) {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add validation for the input parameters.

Consider adding validation to check if the input parameters are valid before using them.

if (tgid < 0 || uid < 0) {
    ALOGW("AppHintDesc: invalid tgid or uid");
    return;
}

Comment on lines +73 to +75
explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
int64_t durationNanos);
~PowerHintSession();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add validation for the input parameters.

Consider adding validation to check if the input parameters are valid before using them.

if (tgid < 0 || uid < 0) {
    ALOGW("PowerHintSession: invalid tgid or uid");
    return;
}

Comment on lines +79 to +126
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
if (HintManager::GetInstance()->GetAdpfProfile() &&
HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) {
PowerSessionManager::getInstance()->updateHintMode(toString(type), enabled);
}
if (setDeviceSpecificMode(type, enabled)) {
return ndk::ScopedAStatus::ok();
}

switch (type) {
case Mode::SUSTAINED_PERFORMANCE:
if (enabled) {
HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE");
}
mSustainedPerfModeOn = true;
break;
case Mode::LAUNCH:
if (mSustainedPerfModeOn) {
break;
}
[[fallthrough]];
case Mode::DOUBLE_TAP_TO_WAKE:
[[fallthrough]];
case Mode::FIXED_PERFORMANCE:
[[fallthrough]];
case Mode::EXPENSIVE_RENDERING:
[[fallthrough]];
case Mode::INTERACTIVE:
[[fallthrough]];
case Mode::DEVICE_IDLE:
[[fallthrough]];
case Mode::DISPLAY_INACTIVE:
[[fallthrough]];
case Mode::AUDIO_STREAMING_LOW_LATENCY:
[[fallthrough]];
case Mode::GAME_LOADING:
[[fallthrough]];
default:
if (enabled) {
HintManager::GetInstance()->DoHint(toString(type));
} else {
HintManager::GetInstance()->EndHint(toString(type));
}
break;
}

return ndk::ScopedAStatus::ok();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for HintManager methods.

The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.

if (enabled) {
    if (!HintManager::GetInstance()->DoHint(toString(type))) {
        LOG(ERROR) << "Failed to apply hint for mode: " << toString(type);
        // Handle the error appropriately
    }
} else {
    if (!HintManager::GetInstance()->EndHint(toString(type))) {
        LOG(ERROR) << "Failed to end hint for mode: " << toString(type);
        // Handle the error appropriately
    }
}

Add error handling for HintManager methods.

The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.

if (enabled) {
    if (!HintManager::GetInstance()->DoHint(toString(type))) {
        LOG(ERROR) << "Failed to apply hint for mode: " << toString(type);
        // Handle the error appropriately
    }
} else {
    if (!HintManager::GetInstance()->EndHint(toString(type))) {
        LOG(ERROR) << "Failed to end hint for mode: " << toString(type);
        // Handle the error appropriately
    }
}

Comment on lines +140 to +174
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
if (HintManager::GetInstance()->GetAdpfProfile() &&
HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) {
PowerSessionManager::getInstance()->updateHintBoost(toString(type), durationMs);
}
switch (type) {
case Boost::INTERACTION:
if (mSustainedPerfModeOn) {
break;
}
mInteractionHandler->Acquire(durationMs);
break;
case Boost::DISPLAY_UPDATE_IMMINENT:
[[fallthrough]];
case Boost::ML_ACC:
[[fallthrough]];
case Boost::AUDIO_LAUNCH:
[[fallthrough]];
default:
if (mSustainedPerfModeOn) {
break;
}
if (durationMs > 0) {
HintManager::GetInstance()->DoHint(toString(type),
std::chrono::milliseconds(durationMs));
} else if (durationMs == 0) {
HintManager::GetInstance()->DoHint(toString(type));
} else {
HintManager::GetInstance()->EndHint(toString(type));
}
break;
}

return ndk::ScopedAStatus::ok();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for HintManager methods.

The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.

if (durationMs > 0) {
    if (!HintManager::GetInstance()->DoHint(toString(type), std::chrono::milliseconds(durationMs))) {
        LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
        // Handle the error appropriately
    }
} else if (durationMs == 0) {
    if (!HintManager::GetInstance()->DoHint(toString(type))) {
        LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
        // Handle the error appropriately
    }
} else {
    if (!HintManager::GetInstance()->EndHint(toString(type))) {
        LOG(ERROR) << "Failed to end hint for boost: " << toString(type);
        // Handle the error appropriately
    }
}

Add error handling for HintManager methods.

The HintManager::DoHint and HintManager::EndHint methods might fail, and this is not currently handled.

if (durationMs > 0) {
    if (!HintManager::GetInstance()->DoHint(toString(type), std::chrono::milliseconds(durationMs))) {
        LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
        // Handle the error appropriately
    }
} else if (durationMs == 0) {
    if (!HintManager::GetInstance()->DoHint(toString(type))) {
        LOG(ERROR) << "Failed to apply hint for boost: " << toString(type);
        // Handle the error appropriately
    }
} else {
    if (!HintManager::GetInstance()->EndHint(toString(type))) {
        LOG(ERROR) << "Failed to end hint for boost: " << toString(type);
        // Handle the error appropriately
    }
}

Comment on lines +57 to +115
int64_t PowerHintSession::convertWorkDurationToBoostByPid(
const std::vector<WorkDuration> &actualDurations) {
std::shared_ptr<AdpfConfig> adpfConfig = HintManager::GetInstance()->GetAdpfProfile();
const nanoseconds &targetDuration = mDescriptor->duration;
int64_t &integral_error = mDescriptor->integral_error;
int64_t &previous_error = mDescriptor->previous_error;
uint64_t samplingWindowP = adpfConfig->mSamplingWindowP;
uint64_t samplingWindowI = adpfConfig->mSamplingWindowI;
uint64_t samplingWindowD = adpfConfig->mSamplingWindowD;
int64_t targetDurationNanos = (int64_t)targetDuration.count();
int64_t length = actualDurations.size();
int64_t p_start =
samplingWindowP == 0 || samplingWindowP > length ? 0 : length - samplingWindowP;
int64_t i_start =
samplingWindowI == 0 || samplingWindowI > length ? 0 : length - samplingWindowI;
int64_t d_start =
samplingWindowD == 0 || samplingWindowD > length ? 0 : length - samplingWindowD;
int64_t dt = ns_to_100us(targetDurationNanos);
int64_t err_sum = 0;
int64_t derivative_sum = 0;
for (int64_t i = std::min({p_start, i_start, d_start}); i < length; i++) {
int64_t actualDurationNanos = actualDurations[i].durationNanos;
if (std::abs(actualDurationNanos) > targetDurationNanos * 20) {
ALOGW("The actual duration is way far from the target (%" PRId64 " >> %" PRId64 ")",
actualDurationNanos, targetDurationNanos);
}
// PID control algorithm
int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos);
if (i >= d_start) {
derivative_sum += error - previous_error;
}
if (i >= p_start) {
err_sum += error;
}
if (i >= i_start) {
integral_error += error * dt;
integral_error = std::min(adpfConfig->getPidIHighDivI(), integral_error);
integral_error = std::max(adpfConfig->getPidILowDivI(), integral_error);
}
previous_error = error;
}
int64_t pOut = static_cast<int64_t>((err_sum > 0 ? adpfConfig->mPidPo : adpfConfig->mPidPu) *
err_sum / (length - p_start));
int64_t iOut = static_cast<int64_t>(adpfConfig->mPidI * integral_error);
int64_t dOut =
static_cast<int64_t>((derivative_sum > 0 ? adpfConfig->mPidDo : adpfConfig->mPidDu) *
derivative_sum / dt / (length - d_start));

int64_t output = pOut + iOut + dOut;
if (ATRACE_ENABLED()) {
traceSessionVal("pid.err", err_sum / (length - p_start));
traceSessionVal("pid.integral", integral_error);
traceSessionVal("pid.derivative", derivative_sum / dt / (length - d_start));
traceSessionVal("pid.pOut", pOut);
traceSessionVal("pid.iOut", iOut);
traceSessionVal("pid.dOut", dOut);
traceSessionVal("pid.output", output);
}
return output;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for potential issues in the PID calculation.

The PID control algorithm might encounter issues, such as division by zero or overflow, and this is not currently handled.

try {
    // PID control algorithm
    int64_t error = ns_to_100us(actualDurationNanos - targetDurationNanos);
    if (i >= d_start) {
        derivative_sum += error - previous_error;
    }
    if (i >= p_start) {
        err_sum += error;
    }
    if (i >= i_start) {
        integral_error += error * dt;
        integral_error = std::min(adpfConfig->getPidIHighDivI(), integral_error);
        integral_error = std::max(adpfConfig->getPidILowDivI(), integral_error);
    }
    previous_error = error;
} catch (const std::exception &e) {
    ALOGE("PID calculation error: %s", e.what());
    // Handle the error appropriately
}

Comment on lines +118 to +137
PowerHintSession::PowerHintSession(int32_t tgid, int32_t uid, const std::vector<int32_t> &threadIds,
int64_t durationNanos)
: mStaleTimerHandler(sp<StaleTimerHandler>::make(this)),
mBoostTimerHandler(sp<BoostTimerHandler>::make(this)) {
mDescriptor = new AppHintDesc(tgid, uid, threadIds);
mDescriptor->duration = std::chrono::nanoseconds(durationNanos);
mIdString = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid,
mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff);

mPowerManagerHandler = PowerSessionManager::getInstance();
mLastUpdatedTime.store(std::chrono::steady_clock::now());
if (ATRACE_ENABLED()) {
traceSessionVal("target", mDescriptor->duration.count());
traceSessionVal("active", mDescriptor->is_active.load());
}
PowerSessionManager::getInstance()->addPowerSession(this);
// init boost
sendHint(SessionHint::CPU_LOAD_RESET);
ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for potential issues in the initialization.

The initialization might encounter issues, such as failed memory allocation or invalid arguments, and this is not currently handled.

try {
    mDescriptor = new AppHintDesc(tgid, uid, threadIds);
    mDescriptor->duration = std::chrono::nanoseconds(durationNanos);
    mIdString = StringPrintf("%" PRId32 "-%" PRId32 "-%" PRIxPTR, mDescriptor->tgid,
                             mDescriptor->uid, reinterpret_cast<uintptr_t>(this) & 0xffff);
    mPowerManagerHandler = PowerSessionManager::getInstance();
    mLastUpdatedTime.store(std::chrono::steady_clock::now());
    if (ATRACE_ENABLED()) {
        traceSessionVal("target", mDescriptor->duration.count());
        traceSessionVal("active", mDescriptor->is_active.load());
    }
    PowerSessionManager::getInstance()->addPowerSession(this);
    // init boost
    sendHint(SessionHint::CPU_LOAD_RESET);
    ALOGV("PowerHintSession created: %s", mDescriptor->toString().c_str());
} catch (const std::exception &e) {
    ALOGE("Initialization error: %s", e.what());
    // Handle the error appropriately
}

Comment on lines +139 to +148
PowerHintSession::~PowerHintSession() {
close();
ALOGV("PowerHintSession deleted: %s", mDescriptor->toString().c_str());
if (ATRACE_ENABLED()) {
traceSessionVal("target", 0);
traceSessionVal("actl_last", 0);
traceSessionVal("active", 0);
}
delete mDescriptor;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for potential issues in the cleanup.

The cleanup might encounter issues, such as failed resource deallocation, and this is not currently handled.

try {
    close();
    ALOGV("PowerHintSession deleted: %s", mDescriptor->toString().c_str());
    if (ATRACE_ENABLED()) {
        traceSessionVal("target", 0);
        traceSessionVal("actl_last", 0);
        traceSessionVal("active", 0);
    }
    delete mDescriptor;
} catch (const std::exception &e) {
    ALOGE("Cleanup error: %s", e.what());
    // Handle the error appropriately
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.