blob: 9791a2504ae5509188d6c4aea1e77fdfeabe0fea [file] [log] [blame]
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +02001/*
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
28namespace android {
29
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080030// Generates pseudo-random IDs of type GpuVirtualDisplayId or HalVirtualDisplayId.
31template <typename Id>
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020032class DisplayIdGenerator {
33public:
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080034 explicit DisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max())
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020035 : mMaxIdsCount(maxIdsCount) {}
36
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080037 bool inUse() const { return !mUsedIds.empty(); }
38
39 std::optional<Id> generateId() {
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020040 if (mUsedIds.size() >= mMaxIdsCount) {
41 return std::nullopt;
42 }
43
44 constexpr int kMaxAttempts = 1000;
45
46 for (int attempts = 0; attempts < kMaxAttempts; attempts++) {
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080047 const Id id{mDistribution(mGenerator)};
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020048 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
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080057 void releaseId(Id id) { mUsedIds.erase(id); }
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020058
59private:
60 const size_t mMaxIdsCount;
61
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080062 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.
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020067 std::default_random_engine mGenerator{std::random_device()()};
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080068 std::uniform_int_distribution<typename Id::BaseId> mDistribution;
Marin Shalamanov0f10d0d2020-08-06 20:04:06 +020069};
70
Dominik Laskowski3dce4f42021-03-08 20:48:28 -080071} // namespace android