1 // Copyright 2018 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 #include "ui/accessibility/ax_tree_id.h"
6 
7 #include <algorithm>
8 #include <iostream>
9 
10 #include "base/check.h"
11 #include "base/no_destructor.h"
12 #include "base/notreached.h"
13 #include "base/util/values/values_util.h"
14 #include "base/values.h"
15 #include "ui/accessibility/ax_enums.mojom.h"
16 
17 namespace ui {
18 
AXTreeID()19 AXTreeID::AXTreeID() : AXTreeID(ax::mojom::AXTreeIDType::kUnknown) {}
20 
21 AXTreeID::AXTreeID(const AXTreeID& other) = default;
22 
AXTreeID(ax::mojom::AXTreeIDType type)23 AXTreeID::AXTreeID(ax::mojom::AXTreeIDType type) : type_(type) {
24   if (type_ == ax::mojom::AXTreeIDType::kToken)
25     token_ = base::UnguessableToken::Create();
26 }
27 
AXTreeID(const std::string & string)28 AXTreeID::AXTreeID(const std::string& string) {
29   if (string.empty()) {
30     type_ = ax::mojom::AXTreeIDType::kUnknown;
31   } else {
32     type_ = ax::mojom::AXTreeIDType::kToken;
33     base::Optional<base::UnguessableToken> token =
34         util::ValueToUnguessableToken(base::Value(string));
35     CHECK(token);
36     token_ = *token;
37   }
38 }
39 
40 // static
FromString(const std::string & string)41 AXTreeID AXTreeID::FromString(const std::string& string) {
42   return AXTreeID(string);
43 }
44 
45 // static
FromToken(const base::UnguessableToken & token)46 AXTreeID AXTreeID::FromToken(const base::UnguessableToken& token) {
47   return AXTreeID(token.ToString());
48 }
49 
50 // static
CreateNewAXTreeID()51 AXTreeID AXTreeID::CreateNewAXTreeID() {
52   return AXTreeID(ax::mojom::AXTreeIDType::kToken);
53 }
54 
55 AXTreeID& AXTreeID::operator=(const AXTreeID& other) = default;
56 
ToString() const57 std::string AXTreeID::ToString() const {
58   switch (type_) {
59     case ax::mojom::AXTreeIDType::kUnknown:
60       return "";
61     case ax::mojom::AXTreeIDType::kToken:
62       return util::UnguessableTokenToValue(*token_).GetString();
63   }
64 
65   NOTREACHED();
66   return std::string();
67 }
68 
swap(AXTreeID & first,AXTreeID & second)69 void swap(AXTreeID& first, AXTreeID& second) {
70   std::swap(first.type_, second.type_);
71   std::swap(first.token_, second.token_);
72 }
73 
operator ==(const AXTreeID & rhs) const74 bool AXTreeID::operator==(const AXTreeID& rhs) const {
75   return type_ == rhs.type_ && token_ == rhs.token_;
76 }
77 
operator !=(const AXTreeID & rhs) const78 bool AXTreeID::operator!=(const AXTreeID& rhs) const {
79   return !(*this == rhs);
80 }
81 
operator <(const AXTreeID & rhs) const82 bool AXTreeID::operator<(const AXTreeID& rhs) const {
83   return std::tie(type_, token_) < std::tie(rhs.type_, rhs.token_);
84 }
85 
operator <=(const AXTreeID & rhs) const86 bool AXTreeID::operator<=(const AXTreeID& rhs) const {
87   return std::tie(type_, token_) <= std::tie(rhs.type_, rhs.token_);
88 }
89 
operator >(const AXTreeID & rhs) const90 bool AXTreeID::operator>(const AXTreeID& rhs) const {
91   return !(*this <= rhs);
92 }
93 
operator >=(const AXTreeID & rhs) const94 bool AXTreeID::operator>=(const AXTreeID& rhs) const {
95   return !(*this < rhs);
96 }
97 
operator ()(const ui::AXTreeID & tree_id) const98 size_t AXTreeIDHash::operator()(const ui::AXTreeID& tree_id) const {
99   DCHECK(tree_id.type() == ax::mojom::AXTreeIDType::kToken);
100   return base::UnguessableTokenHash()(tree_id.token().value());
101 }
102 
operator <<(std::ostream & stream,const AXTreeID & value)103 std::ostream& operator<<(std::ostream& stream, const AXTreeID& value) {
104   return stream << value.ToString();
105 }
106 
AXTreeIDUnknown()107 const AXTreeID& AXTreeIDUnknown() {
108   static const base::NoDestructor<AXTreeID> ax_tree_id_unknown(
109       ax::mojom::AXTreeIDType::kUnknown);
110   return *ax_tree_id_unknown;
111 }
112 
113 }  // namespace ui
114