1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_EXECUTION_CONTEXT_PRIORITY_OVERRIDE_VOTE_AGGREGATOR_H_
6 #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_EXECUTION_CONTEXT_PRIORITY_OVERRIDE_VOTE_AGGREGATOR_H_
7 
8 #include <map>
9 
10 #include "components/performance_manager/public/execution_context_priority/execution_context_priority.h"
11 
12 namespace performance_manager {
13 namespace execution_context_priority {
14 
15 // Aggregator that allows votes from 2 different Voters, where one of the voters
16 // is allowed to override the votes of another. This aggregator should be
17 // completely setup before any votes are submitted to it.
18 class OverrideVoteAggregator : public VoteConsumer {
19  public:
20   OverrideVoteAggregator();
21   ~OverrideVoteAggregator() override;
22 
23   // All 3 of these must have been called in order for the aggregator to be
24   // fully setup.
25   VotingChannel GetOverrideVotingChannel();
26   VotingChannel GetDefaultVotingChannel();
27   void SetUpstreamVotingChannel(VotingChannel&& channel);
28 
29   bool IsSetup() const;
30 
GetSizeForTesting()31   size_t GetSizeForTesting() const { return vote_data_map_.size(); }
32 
33  protected:
34   // VoteConsumer implementation:
35   VoteReceipt SubmitVote(util::PassKey<VotingChannel>,
36                          voting::VoterId<Vote> voter_id,
37                          const ExecutionContext* execution_context,
38                          const Vote& vote) override;
39   void ChangeVote(util::PassKey<AcceptedVote>,
40                   AcceptedVote* old_vote,
41                   const Vote& new_vote) override;
42   void VoteInvalidated(util::PassKey<AcceptedVote>,
43                        AcceptedVote* vote) override;
44 
45  private:
46   // This is move-only because all of its members are move-only.
47   struct VoteData {
48     VoteData();
49     VoteData(const VoteData& rhs) = delete;
50     VoteData(VoteData&& rhs);
51     VoteData& operator=(const VoteData& rhs) = delete;
52     VoteData& operator=(VoteData&& rhs) = default;
53     ~VoteData();
54 
55     // Each of these IsValid if a vote has been emitted for this execution
56     // context, otherwise !IsValid. At least one of the votes must be valid,
57     // otherwise the entire map entry will be destroyed.
58     AcceptedVote override_vote;
59     AcceptedVote default_vote;
60 
61     // The receipt for the vote we've upstreamed.
62     VoteReceipt receipt;
63   };
64 
65   using VoteDataMap = std::map<const ExecutionContext*, VoteData>;
66 
67   // Looks up the VoteData associated with the provided |vote|. The data is
68   // expected to already exist (enforced by a DCHECK).
69   VoteDataMap::iterator GetVoteData(AcceptedVote* vote);
70 
71   // Rebrands |vote| as belonging to this voter, and then sends it along to our
72   // |consumer_|. Stores the resulting receipt in |vote_data|.
73   void UpstreamVote(const ExecutionContext* execution_context,
74                     const Vote& vote,
75                     VoteData* vote_data);
76 
77   // Our two input voters. We'll only accept votes from these voters otherwise
78   // we'll DCHECK.
79   voting::VoterId<Vote> override_voter_id_ = voting::kInvalidVoterId<Vote>;
80   voting::VoterId<Vote> default_voter_id_ = voting::kInvalidVoterId<Vote>;
81 
82   // Our channel for upstreaming our votes.
83   VotingChannel channel_;
84 
85   // Our VotingChannelFactory for providing VotingChannels to our input voters.
86   VotingChannelFactory factory_;
87 
88   // The votes we've upstreamed to our consumer.
89   VoteDataMap vote_data_map_;
90 
91   DISALLOW_COPY_AND_ASSIGN(OverrideVoteAggregator);
92 };
93 
94 }  // namespace execution_context_priority
95 }  // namespace performance_manager
96 
97 #endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_EXECUTION_CONTEXT_PRIORITY_OVERRIDE_VOTE_AGGREGATOR_H_
98