• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.display.mode;
18 
19 import static com.android.internal.util.FrameworkStatsLog.DISPLAY_MODE_DIRECTOR_VOTE_CHANGED;
20 import static com.android.internal.util.FrameworkStatsLog.DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_ACTIVE;
21 import static com.android.internal.util.FrameworkStatsLog.DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_ADDED;
22 import static com.android.internal.util.FrameworkStatsLog.DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_REMOVED;
23 
24 import android.annotation.NonNull;
25 import android.annotation.Nullable;
26 import android.os.Trace;
27 import android.util.SparseArray;
28 import android.util.SparseIntArray;
29 import android.view.Display;
30 
31 import com.android.internal.util.FrameworkStatsLog;
32 
33 /**
34  * The VotesStatsReporter is responsible for collecting and sending Vote related statistics
35  */
36 class VotesStatsReporter {
37     private static final String TAG = "VotesStatsReporter";
38     private static final int REFRESH_RATE_NOT_LIMITED = 1000;
39     private final boolean mIgnoredRenderRate;
40 
41     private final SparseIntArray mLastMinPriorityByDisplay = new SparseIntArray();
42 
VotesStatsReporter(boolean ignoreRenderRate)43     VotesStatsReporter(boolean ignoreRenderRate) {
44         mIgnoredRenderRate = ignoreRenderRate;
45     }
46 
reportVoteChanged(int displayId, int priority, @Nullable Vote vote)47     void reportVoteChanged(int displayId, int priority,  @Nullable Vote vote) {
48         if (vote == null) {
49             reportVoteRemoved(displayId, priority);
50         } else {
51             reportVoteAdded(displayId, priority, vote);
52         }
53     }
54 
reportVoteAdded(int displayId, int priority, @NonNull Vote vote)55     private void reportVoteAdded(int displayId, int priority,  @NonNull Vote vote) {
56         int maxRefreshRate = getMaxRefreshRate(vote, mIgnoredRenderRate);
57         Trace.traceCounter(Trace.TRACE_TAG_POWER,
58                 TAG + "." + displayId + ":" + Vote.priorityToString(priority), maxRefreshRate);
59         FrameworkStatsLog.write(
60                 DISPLAY_MODE_DIRECTOR_VOTE_CHANGED, displayId, priority,
61                 DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_ADDED,
62                 maxRefreshRate, -1);
63     }
64 
reportVoteRemoved(int displayId, int priority)65     private void reportVoteRemoved(int displayId, int priority) {
66         Trace.traceCounter(Trace.TRACE_TAG_POWER,
67                 TAG + "." + displayId + ":" + Vote.priorityToString(priority), -1);
68         FrameworkStatsLog.write(
69                 DISPLAY_MODE_DIRECTOR_VOTE_CHANGED, displayId, priority,
70                 DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_REMOVED, -1, -1);
71     }
72 
reportVotesActivated(int displayId, int minPriority, @Nullable Display.Mode baseMode, SparseArray<Vote> votes)73     void reportVotesActivated(int displayId, int minPriority, @Nullable Display.Mode baseMode,
74             SparseArray<Vote> votes) {
75         int lastMinPriorityReported = mLastMinPriorityByDisplay.get(
76                 displayId, Vote.MAX_PRIORITY + 1);
77         int selectedRefreshRate = baseMode != null ? (int) baseMode.getRefreshRate() : -1;
78         for (int priority = Vote.MIN_PRIORITY; priority <= Vote.MAX_PRIORITY; priority++) {
79             if (priority < lastMinPriorityReported && priority < minPriority) {
80                 continue;
81             }
82             Vote vote = votes.get(priority);
83             if (vote == null) {
84                 continue;
85             }
86 
87             // Was previously reported ACTIVE, changed to ADDED
88             if (priority >= lastMinPriorityReported && priority < minPriority) {
89                 int maxRefreshRate = getMaxRefreshRate(vote, mIgnoredRenderRate);
90                 FrameworkStatsLog.write(
91                         DISPLAY_MODE_DIRECTOR_VOTE_CHANGED, displayId, priority,
92                         DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_ADDED,
93                         maxRefreshRate, selectedRefreshRate);
94             }
95             // Was previously reported ADDED, changed to ACTIVE
96             if (priority >= minPriority && priority < lastMinPriorityReported) {
97                 int maxRefreshRate = getMaxRefreshRate(vote, mIgnoredRenderRate);
98                 FrameworkStatsLog.write(
99                         DISPLAY_MODE_DIRECTOR_VOTE_CHANGED, displayId, priority,
100                         DISPLAY_MODE_DIRECTOR_VOTE_CHANGED__VOTE_STATUS__STATUS_ACTIVE,
101                         maxRefreshRate, selectedRefreshRate);
102             }
103 
104             mLastMinPriorityByDisplay.put(displayId, minPriority);
105         }
106     }
107 
getMaxRefreshRate(@onNull Vote vote, boolean ignoreRenderRate)108     private static int getMaxRefreshRate(@NonNull Vote vote, boolean ignoreRenderRate) {
109         int maxRefreshRate = REFRESH_RATE_NOT_LIMITED;
110         if (vote instanceof RefreshRateVote.PhysicalVote physicalVote) {
111             maxRefreshRate = (int) physicalVote.mMaxRefreshRate;
112         } else if (!ignoreRenderRate && (vote instanceof RefreshRateVote.RenderVote renderVote)) {
113             maxRefreshRate = (int)  renderVote.mMaxRefreshRate;
114         } else if (vote instanceof SupportedRefreshRatesVote refreshRatesVote) {
115             // SupportedRefreshRatesVote limits mode by refreshRates, so highest rr is allowed
116             maxRefreshRate = 0;
117             for (SupportedRefreshRatesVote.RefreshRates rr : refreshRatesVote.mRefreshRates) {
118                 maxRefreshRate = Math.max(maxRefreshRate, (int) rr.mPeakRefreshRate);
119             }
120         } else if (vote instanceof CombinedVote combinedVote) {
121             for (Vote subVote: combinedVote.mVotes) {
122                 // CombinedVote should not have CombinedVote in mVotes, so recursion depth will be 1
123                 maxRefreshRate = Math.min(maxRefreshRate,
124                         getMaxRefreshRate(subVote, ignoreRenderRate));
125             }
126         }
127         return maxRefreshRate;
128     }
129 }
130