1 /* 2 * Copyright (C) 2020 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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_TRACKER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_TRACKER_H_ 19 20 #include <optional> 21 #include <set> 22 23 #include "perfetto/ext/base/string_view.h" 24 25 #include "src/trace_processor/storage/trace_storage.h" 26 #include "src/trace_processor/types/trace_processor_context.h" 27 28 namespace perfetto { 29 namespace trace_processor { 30 31 class TraceProcessorContext; 32 33 class AndroidProbesTracker : public Destructible { 34 public: 35 explicit AndroidProbesTracker(TraceStorage*); 36 ~AndroidProbesTracker() override; 37 38 // For EnergyBreakdown Descriptor specifications 39 struct EnergyConsumerSpecs { 40 StringId name; 41 StringId type; 42 int32_t ordinal; 43 }; 44 45 struct EntityStateDescriptor { 46 StringId entity_name; 47 StringId state_name; 48 StringId overall_name; 49 }; 50 GetOrCreate(TraceProcessorContext * context)51 static AndroidProbesTracker* GetOrCreate(TraceProcessorContext* context) { 52 if (!context->android_probes_tracker) { 53 context->android_probes_tracker.reset( 54 new AndroidProbesTracker(context->storage.get())); 55 } 56 return static_cast<AndroidProbesTracker*>( 57 context->android_probes_tracker.get()); 58 } 59 ShouldInsertPackage(const std::string & package_name)60 bool ShouldInsertPackage(const std::string& package_name) const { 61 auto it = seen_packages_.find(package_name); 62 return it == seen_packages_.end(); 63 } 64 InsertedPackage(std::string package_name)65 void InsertedPackage(std::string package_name) { 66 seen_packages_.emplace(std::move(package_name)); 67 } 68 GetPowerRailTrack(uint32_t index)69 std::optional<TrackId> GetPowerRailTrack(uint32_t index) { 70 if (index >= power_rail_tracks_.size()) 71 return std::nullopt; 72 TrackId track_id = power_rail_tracks_[index]; 73 return track_id == kInvalidTrackId ? std::nullopt 74 : std::make_optional(track_id); 75 } 76 SetPowerRailTrack(uint32_t index,TrackId track_id)77 void SetPowerRailTrack(uint32_t index, TrackId track_id) { 78 if (power_rail_tracks_.size() <= index) 79 power_rail_tracks_.resize(index + 1, kInvalidTrackId); 80 power_rail_tracks_[index] = track_id; 81 } 82 GetEnergyBreakdownDescriptor(int32_t consumer_id)83 std::optional<EnergyConsumerSpecs> GetEnergyBreakdownDescriptor( 84 int32_t consumer_id) { 85 auto it = energy_consumer_descriptors_.find(consumer_id); 86 // Didn't receive the descriptor 87 if (it == energy_consumer_descriptors_.end()) { 88 return std::nullopt; 89 } 90 return it->second; 91 } 92 SetEnergyBreakdownDescriptor(int32_t consumer_id,StringId name,StringId type,int32_t ordinal)93 void SetEnergyBreakdownDescriptor(int32_t consumer_id, 94 StringId name, 95 StringId type, 96 int32_t ordinal) { 97 auto it_consumer_descriptor = 98 energy_consumer_descriptors_.find(consumer_id); 99 100 // Either descriptor was repeated or it came after per uid data. 101 if (it_consumer_descriptor != energy_consumer_descriptors_.end()) 102 return; 103 104 energy_consumer_descriptors_[consumer_id] = 105 EnergyConsumerSpecs{name, type, ordinal}; 106 } 107 GetEntityStateDescriptor(int32_t entity_id,int32_t state_id)108 std::optional<EntityStateDescriptor> GetEntityStateDescriptor( 109 int32_t entity_id, 110 int32_t state_id) { 111 uint64_t id = EntityStateKey(entity_id, state_id); 112 auto it = entity_state_descriptors_.find(id); 113 // Didn't receive the descriptor 114 if (it == entity_state_descriptors_.end()) { 115 return std::nullopt; 116 } 117 return it->second; 118 } 119 SetEntityStateDescriptor(int32_t entity_id,int32_t state_id,StringId entity_name,StringId state_name)120 void SetEntityStateDescriptor(int32_t entity_id, 121 int32_t state_id, 122 StringId entity_name, 123 StringId state_name) { 124 uint64_t id = EntityStateKey(entity_id, state_id); 125 auto it_descriptor = entity_state_descriptors_.find(id); 126 127 // Ignore repeated descriptors. 128 if (it_descriptor != entity_state_descriptors_.end()) 129 return; 130 131 std::string overall_str = 132 "Entity residency: " + storage_->GetString(entity_name).ToStdString() + 133 " is " + storage_->GetString(state_name).ToStdString(); 134 135 StringId overall = storage_->InternString(base::StringView(overall_str)); 136 137 entity_state_descriptors_[id] = 138 EntityStateDescriptor{entity_name, state_name, overall}; 139 } 140 141 private: 142 TraceStorage* storage_; 143 std::set<std::string> seen_packages_; 144 std::vector<TrackId> power_rail_tracks_; 145 std::unordered_map<int32_t, EnergyConsumerSpecs> energy_consumer_descriptors_; 146 std::unordered_map<uint64_t, EntityStateDescriptor> entity_state_descriptors_; 147 EntityStateKey(int32_t entity_id,int32_t state_id)148 uint64_t EntityStateKey(int32_t entity_id, int32_t state_id) { 149 return (static_cast<uint64_t>(entity_id) << 32) | 150 static_cast<uint32_t>(state_id); 151 } 152 }; 153 154 } // namespace trace_processor 155 } // namespace perfetto 156 157 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ANDROID_PROBES_TRACKER_H_ 158