• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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