1 /* 2 * Copyright 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 #pragma once 18 19 #include <ui/DisplayId.h> 20 21 #include <limits> 22 #include <optional> 23 #include <random> 24 #include <unordered_set> 25 26 #include <log/log.h> 27 28 namespace android { 29 30 // Generates pseudo-random IDs of type GpuVirtualDisplayId or HalVirtualDisplayId. 31 template <typename Id> 32 class DisplayIdGenerator { 33 public: 34 explicit DisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max()) mMaxIdsCount(maxIdsCount)35 : mMaxIdsCount(maxIdsCount) {} 36 inUse()37 bool inUse() const { return !mUsedIds.empty(); } 38 generateId()39 std::optional<Id> generateId() { 40 if (mUsedIds.size() >= mMaxIdsCount) { 41 return std::nullopt; 42 } 43 44 constexpr int kMaxAttempts = 1000; 45 46 for (int attempts = 0; attempts < kMaxAttempts; attempts++) { 47 const Id id{mDistribution(mGenerator)}; 48 if (mUsedIds.count(id) == 0) { 49 mUsedIds.insert(id); 50 return id; 51 } 52 } 53 54 LOG_ALWAYS_FATAL("Couldn't generate ID after %d attempts", kMaxAttempts); 55 } 56 releaseId(Id id)57 void releaseId(Id id) { mUsedIds.erase(id); } 58 59 private: 60 const size_t mMaxIdsCount; 61 62 std::unordered_set<Id> mUsedIds; 63 64 // Pseudo-random with random seed, in contrast to physical display IDs, which are stable 65 // across reboots. The only ISurfaceComposer exposure for these IDs is a restricted API 66 // for screencap, so there is little benefit in making them unpredictable. 67 std::default_random_engine mGenerator{std::random_device()()}; 68 std::uniform_int_distribution<typename Id::BaseId> mDistribution; 69 }; 70 71 } // namespace android 72