xref: /aosp_15_r20/external/libchrome/dbus/values_util.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "dbus/values_util.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <memory>
8*635a8641SAndroid Build Coastguard Worker #include <utility>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
13*635a8641SAndroid Build Coastguard Worker #include "dbus/message.h"
14*635a8641SAndroid Build Coastguard Worker 
15*635a8641SAndroid Build Coastguard Worker namespace dbus {
16*635a8641SAndroid Build Coastguard Worker 
17*635a8641SAndroid Build Coastguard Worker namespace {
18*635a8641SAndroid Build Coastguard Worker 
19*635a8641SAndroid Build Coastguard Worker // Returns whether |value| is exactly representable by double or not.
20*635a8641SAndroid Build Coastguard Worker template<typename T>
IsExactlyRepresentableByDouble(T value)21*635a8641SAndroid Build Coastguard Worker bool IsExactlyRepresentableByDouble(T value) {
22*635a8641SAndroid Build Coastguard Worker   return value == static_cast<T>(static_cast<double>(value));
23*635a8641SAndroid Build Coastguard Worker }
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker // Pops values from |reader| and appends them to |list_value|.
PopListElements(MessageReader * reader,base::ListValue * list_value)26*635a8641SAndroid Build Coastguard Worker bool PopListElements(MessageReader* reader, base::ListValue* list_value) {
27*635a8641SAndroid Build Coastguard Worker   while (reader->HasMoreData()) {
28*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<base::Value> element_value = PopDataAsValue(reader);
29*635a8641SAndroid Build Coastguard Worker     if (!element_value)
30*635a8641SAndroid Build Coastguard Worker       return false;
31*635a8641SAndroid Build Coastguard Worker     list_value->Append(std::move(element_value));
32*635a8641SAndroid Build Coastguard Worker   }
33*635a8641SAndroid Build Coastguard Worker   return true;
34*635a8641SAndroid Build Coastguard Worker }
35*635a8641SAndroid Build Coastguard Worker 
36*635a8641SAndroid Build Coastguard Worker // Pops dict-entries from |reader| and sets them to |dictionary_value|
PopDictionaryEntries(MessageReader * reader,base::DictionaryValue * dictionary_value)37*635a8641SAndroid Build Coastguard Worker bool PopDictionaryEntries(MessageReader* reader,
38*635a8641SAndroid Build Coastguard Worker                           base::DictionaryValue* dictionary_value) {
39*635a8641SAndroid Build Coastguard Worker   while (reader->HasMoreData()) {
40*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(Message::DICT_ENTRY, reader->GetDataType());
41*635a8641SAndroid Build Coastguard Worker     MessageReader entry_reader(nullptr);
42*635a8641SAndroid Build Coastguard Worker     if (!reader->PopDictEntry(&entry_reader))
43*635a8641SAndroid Build Coastguard Worker       return false;
44*635a8641SAndroid Build Coastguard Worker     // Get key as a string.
45*635a8641SAndroid Build Coastguard Worker     std::string key_string;
46*635a8641SAndroid Build Coastguard Worker     if (entry_reader.GetDataType() == Message::STRING) {
47*635a8641SAndroid Build Coastguard Worker       // If the type of keys is STRING, pop it directly.
48*635a8641SAndroid Build Coastguard Worker       if (!entry_reader.PopString(&key_string))
49*635a8641SAndroid Build Coastguard Worker         return false;
50*635a8641SAndroid Build Coastguard Worker     } else {
51*635a8641SAndroid Build Coastguard Worker       // If the type of keys is not STRING, convert it to string.
52*635a8641SAndroid Build Coastguard Worker       std::unique_ptr<base::Value> key(PopDataAsValue(&entry_reader));
53*635a8641SAndroid Build Coastguard Worker       if (!key)
54*635a8641SAndroid Build Coastguard Worker         return false;
55*635a8641SAndroid Build Coastguard Worker       // Use JSONWriter to convert an arbitrary value to a string.
56*635a8641SAndroid Build Coastguard Worker       base::JSONWriter::Write(*key, &key_string);
57*635a8641SAndroid Build Coastguard Worker     }
58*635a8641SAndroid Build Coastguard Worker     // Get the value and set the key-value pair.
59*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<base::Value> value = PopDataAsValue(&entry_reader);
60*635a8641SAndroid Build Coastguard Worker     if (!value)
61*635a8641SAndroid Build Coastguard Worker       return false;
62*635a8641SAndroid Build Coastguard Worker     dictionary_value->SetWithoutPathExpansion(key_string, std::move(value));
63*635a8641SAndroid Build Coastguard Worker   }
64*635a8641SAndroid Build Coastguard Worker   return true;
65*635a8641SAndroid Build Coastguard Worker }
66*635a8641SAndroid Build Coastguard Worker 
67*635a8641SAndroid Build Coastguard Worker // Gets the D-Bus type signature for the value.
GetTypeSignature(const base::Value & value)68*635a8641SAndroid Build Coastguard Worker std::string GetTypeSignature(const base::Value& value) {
69*635a8641SAndroid Build Coastguard Worker   switch (value.type()) {
70*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::BOOLEAN:
71*635a8641SAndroid Build Coastguard Worker       return "b";
72*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::INTEGER:
73*635a8641SAndroid Build Coastguard Worker       return "i";
74*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::DOUBLE:
75*635a8641SAndroid Build Coastguard Worker       return "d";
76*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::STRING:
77*635a8641SAndroid Build Coastguard Worker       return "s";
78*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::BINARY:
79*635a8641SAndroid Build Coastguard Worker       return "ay";
80*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::DICTIONARY:
81*635a8641SAndroid Build Coastguard Worker       return "a{sv}";
82*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::LIST:
83*635a8641SAndroid Build Coastguard Worker       return "av";
84*635a8641SAndroid Build Coastguard Worker     default:
85*635a8641SAndroid Build Coastguard Worker       DLOG(ERROR) << "Unexpected type " << value.type();
86*635a8641SAndroid Build Coastguard Worker       return std::string();
87*635a8641SAndroid Build Coastguard Worker   }
88*635a8641SAndroid Build Coastguard Worker }
89*635a8641SAndroid Build Coastguard Worker 
90*635a8641SAndroid Build Coastguard Worker }  // namespace
91*635a8641SAndroid Build Coastguard Worker 
PopDataAsValue(MessageReader * reader)92*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::Value> PopDataAsValue(MessageReader* reader) {
93*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<base::Value> result;
94*635a8641SAndroid Build Coastguard Worker   switch (reader->GetDataType()) {
95*635a8641SAndroid Build Coastguard Worker     case Message::INVALID_DATA:
96*635a8641SAndroid Build Coastguard Worker       // Do nothing.
97*635a8641SAndroid Build Coastguard Worker       break;
98*635a8641SAndroid Build Coastguard Worker     case Message::BYTE: {
99*635a8641SAndroid Build Coastguard Worker       uint8_t value = 0;
100*635a8641SAndroid Build Coastguard Worker       if (reader->PopByte(&value))
101*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
102*635a8641SAndroid Build Coastguard Worker       break;
103*635a8641SAndroid Build Coastguard Worker     }
104*635a8641SAndroid Build Coastguard Worker     case Message::BOOL: {
105*635a8641SAndroid Build Coastguard Worker       bool value = false;
106*635a8641SAndroid Build Coastguard Worker       if (reader->PopBool(&value))
107*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
108*635a8641SAndroid Build Coastguard Worker       break;
109*635a8641SAndroid Build Coastguard Worker     }
110*635a8641SAndroid Build Coastguard Worker     case Message::INT16: {
111*635a8641SAndroid Build Coastguard Worker       int16_t value = 0;
112*635a8641SAndroid Build Coastguard Worker       if (reader->PopInt16(&value))
113*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
114*635a8641SAndroid Build Coastguard Worker       break;
115*635a8641SAndroid Build Coastguard Worker     }
116*635a8641SAndroid Build Coastguard Worker     case Message::UINT16: {
117*635a8641SAndroid Build Coastguard Worker       uint16_t value = 0;
118*635a8641SAndroid Build Coastguard Worker       if (reader->PopUint16(&value))
119*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
120*635a8641SAndroid Build Coastguard Worker       break;
121*635a8641SAndroid Build Coastguard Worker     }
122*635a8641SAndroid Build Coastguard Worker     case Message::INT32: {
123*635a8641SAndroid Build Coastguard Worker       int32_t value = 0;
124*635a8641SAndroid Build Coastguard Worker       if (reader->PopInt32(&value))
125*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
126*635a8641SAndroid Build Coastguard Worker       break;
127*635a8641SAndroid Build Coastguard Worker     }
128*635a8641SAndroid Build Coastguard Worker     case Message::UINT32: {
129*635a8641SAndroid Build Coastguard Worker       uint32_t value = 0;
130*635a8641SAndroid Build Coastguard Worker       if (reader->PopUint32(&value)) {
131*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(static_cast<double>(value));
132*635a8641SAndroid Build Coastguard Worker       }
133*635a8641SAndroid Build Coastguard Worker       break;
134*635a8641SAndroid Build Coastguard Worker     }
135*635a8641SAndroid Build Coastguard Worker     case Message::INT64: {
136*635a8641SAndroid Build Coastguard Worker       int64_t value = 0;
137*635a8641SAndroid Build Coastguard Worker       if (reader->PopInt64(&value)) {
138*635a8641SAndroid Build Coastguard Worker         DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) <<
139*635a8641SAndroid Build Coastguard Worker             value << " is not exactly representable by double";
140*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(static_cast<double>(value));
141*635a8641SAndroid Build Coastguard Worker       }
142*635a8641SAndroid Build Coastguard Worker       break;
143*635a8641SAndroid Build Coastguard Worker     }
144*635a8641SAndroid Build Coastguard Worker     case Message::UINT64: {
145*635a8641SAndroid Build Coastguard Worker       uint64_t value = 0;
146*635a8641SAndroid Build Coastguard Worker       if (reader->PopUint64(&value)) {
147*635a8641SAndroid Build Coastguard Worker         DLOG_IF(WARNING, !IsExactlyRepresentableByDouble(value)) <<
148*635a8641SAndroid Build Coastguard Worker             value << " is not exactly representable by double";
149*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(static_cast<double>(value));
150*635a8641SAndroid Build Coastguard Worker       }
151*635a8641SAndroid Build Coastguard Worker       break;
152*635a8641SAndroid Build Coastguard Worker     }
153*635a8641SAndroid Build Coastguard Worker     case Message::DOUBLE: {
154*635a8641SAndroid Build Coastguard Worker       double value = 0;
155*635a8641SAndroid Build Coastguard Worker       if (reader->PopDouble(&value))
156*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
157*635a8641SAndroid Build Coastguard Worker       break;
158*635a8641SAndroid Build Coastguard Worker     }
159*635a8641SAndroid Build Coastguard Worker     case Message::STRING: {
160*635a8641SAndroid Build Coastguard Worker       std::string value;
161*635a8641SAndroid Build Coastguard Worker       if (reader->PopString(&value))
162*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value);
163*635a8641SAndroid Build Coastguard Worker       break;
164*635a8641SAndroid Build Coastguard Worker     }
165*635a8641SAndroid Build Coastguard Worker     case Message::OBJECT_PATH: {
166*635a8641SAndroid Build Coastguard Worker       ObjectPath value;
167*635a8641SAndroid Build Coastguard Worker       if (reader->PopObjectPath(&value))
168*635a8641SAndroid Build Coastguard Worker         result = std::make_unique<base::Value>(value.value());
169*635a8641SAndroid Build Coastguard Worker       break;
170*635a8641SAndroid Build Coastguard Worker     }
171*635a8641SAndroid Build Coastguard Worker     case Message::UNIX_FD: {
172*635a8641SAndroid Build Coastguard Worker       // Cannot distinguish a file descriptor from an int
173*635a8641SAndroid Build Coastguard Worker       NOTREACHED();
174*635a8641SAndroid Build Coastguard Worker       break;
175*635a8641SAndroid Build Coastguard Worker     }
176*635a8641SAndroid Build Coastguard Worker     case Message::ARRAY: {
177*635a8641SAndroid Build Coastguard Worker       MessageReader sub_reader(nullptr);
178*635a8641SAndroid Build Coastguard Worker       if (reader->PopArray(&sub_reader)) {
179*635a8641SAndroid Build Coastguard Worker         // If the type of the array's element is DICT_ENTRY, create a
180*635a8641SAndroid Build Coastguard Worker         // DictionaryValue, otherwise create a ListValue.
181*635a8641SAndroid Build Coastguard Worker         if (sub_reader.GetDataType() == Message::DICT_ENTRY) {
182*635a8641SAndroid Build Coastguard Worker           std::unique_ptr<base::DictionaryValue> dictionary_value(
183*635a8641SAndroid Build Coastguard Worker               new base::DictionaryValue);
184*635a8641SAndroid Build Coastguard Worker           if (PopDictionaryEntries(&sub_reader, dictionary_value.get()))
185*635a8641SAndroid Build Coastguard Worker             result = std::move(dictionary_value);
186*635a8641SAndroid Build Coastguard Worker         } else {
187*635a8641SAndroid Build Coastguard Worker           std::unique_ptr<base::ListValue> list_value(new base::ListValue);
188*635a8641SAndroid Build Coastguard Worker           if (PopListElements(&sub_reader, list_value.get()))
189*635a8641SAndroid Build Coastguard Worker             result = std::move(list_value);
190*635a8641SAndroid Build Coastguard Worker         }
191*635a8641SAndroid Build Coastguard Worker       }
192*635a8641SAndroid Build Coastguard Worker       break;
193*635a8641SAndroid Build Coastguard Worker     }
194*635a8641SAndroid Build Coastguard Worker     case Message::STRUCT: {
195*635a8641SAndroid Build Coastguard Worker       MessageReader sub_reader(nullptr);
196*635a8641SAndroid Build Coastguard Worker       if (reader->PopStruct(&sub_reader)) {
197*635a8641SAndroid Build Coastguard Worker         std::unique_ptr<base::ListValue> list_value(new base::ListValue);
198*635a8641SAndroid Build Coastguard Worker         if (PopListElements(&sub_reader, list_value.get()))
199*635a8641SAndroid Build Coastguard Worker           result = std::move(list_value);
200*635a8641SAndroid Build Coastguard Worker       }
201*635a8641SAndroid Build Coastguard Worker       break;
202*635a8641SAndroid Build Coastguard Worker     }
203*635a8641SAndroid Build Coastguard Worker     case Message::DICT_ENTRY:
204*635a8641SAndroid Build Coastguard Worker       // DICT_ENTRY must be popped as an element of an array.
205*635a8641SAndroid Build Coastguard Worker       NOTREACHED();
206*635a8641SAndroid Build Coastguard Worker       break;
207*635a8641SAndroid Build Coastguard Worker     case Message::VARIANT: {
208*635a8641SAndroid Build Coastguard Worker       MessageReader sub_reader(nullptr);
209*635a8641SAndroid Build Coastguard Worker       if (reader->PopVariant(&sub_reader))
210*635a8641SAndroid Build Coastguard Worker         result = PopDataAsValue(&sub_reader);
211*635a8641SAndroid Build Coastguard Worker       break;
212*635a8641SAndroid Build Coastguard Worker     }
213*635a8641SAndroid Build Coastguard Worker   }
214*635a8641SAndroid Build Coastguard Worker   return result;
215*635a8641SAndroid Build Coastguard Worker }
216*635a8641SAndroid Build Coastguard Worker 
AppendBasicTypeValueData(MessageWriter * writer,const base::Value & value)217*635a8641SAndroid Build Coastguard Worker void AppendBasicTypeValueData(MessageWriter* writer, const base::Value& value) {
218*635a8641SAndroid Build Coastguard Worker   switch (value.type()) {
219*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::BOOLEAN: {
220*635a8641SAndroid Build Coastguard Worker       bool bool_value = false;
221*635a8641SAndroid Build Coastguard Worker       bool success = value.GetAsBoolean(&bool_value);
222*635a8641SAndroid Build Coastguard Worker       DCHECK(success);
223*635a8641SAndroid Build Coastguard Worker       writer->AppendBool(bool_value);
224*635a8641SAndroid Build Coastguard Worker       break;
225*635a8641SAndroid Build Coastguard Worker     }
226*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::INTEGER: {
227*635a8641SAndroid Build Coastguard Worker       int int_value = 0;
228*635a8641SAndroid Build Coastguard Worker       bool success = value.GetAsInteger(&int_value);
229*635a8641SAndroid Build Coastguard Worker       DCHECK(success);
230*635a8641SAndroid Build Coastguard Worker       writer->AppendInt32(int_value);
231*635a8641SAndroid Build Coastguard Worker       break;
232*635a8641SAndroid Build Coastguard Worker     }
233*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::DOUBLE: {
234*635a8641SAndroid Build Coastguard Worker       double double_value = 0;
235*635a8641SAndroid Build Coastguard Worker       bool success = value.GetAsDouble(&double_value);
236*635a8641SAndroid Build Coastguard Worker       DCHECK(success);
237*635a8641SAndroid Build Coastguard Worker       writer->AppendDouble(double_value);
238*635a8641SAndroid Build Coastguard Worker       break;
239*635a8641SAndroid Build Coastguard Worker     }
240*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::STRING: {
241*635a8641SAndroid Build Coastguard Worker       std::string string_value;
242*635a8641SAndroid Build Coastguard Worker       bool success = value.GetAsString(&string_value);
243*635a8641SAndroid Build Coastguard Worker       DCHECK(success);
244*635a8641SAndroid Build Coastguard Worker       writer->AppendString(string_value);
245*635a8641SAndroid Build Coastguard Worker       break;
246*635a8641SAndroid Build Coastguard Worker     }
247*635a8641SAndroid Build Coastguard Worker     default:
248*635a8641SAndroid Build Coastguard Worker       DLOG(ERROR) << "Unexpected type " << value.type();
249*635a8641SAndroid Build Coastguard Worker       break;
250*635a8641SAndroid Build Coastguard Worker   }
251*635a8641SAndroid Build Coastguard Worker }
252*635a8641SAndroid Build Coastguard Worker 
AppendBasicTypeValueDataAsVariant(MessageWriter * writer,const base::Value & value)253*635a8641SAndroid Build Coastguard Worker void AppendBasicTypeValueDataAsVariant(MessageWriter* writer,
254*635a8641SAndroid Build Coastguard Worker                                        const base::Value& value) {
255*635a8641SAndroid Build Coastguard Worker   MessageWriter sub_writer(nullptr);
256*635a8641SAndroid Build Coastguard Worker   writer->OpenVariant(GetTypeSignature(value), &sub_writer);
257*635a8641SAndroid Build Coastguard Worker   AppendBasicTypeValueData(&sub_writer, value);
258*635a8641SAndroid Build Coastguard Worker   writer->CloseContainer(&sub_writer);
259*635a8641SAndroid Build Coastguard Worker }
260*635a8641SAndroid Build Coastguard Worker 
AppendValueData(MessageWriter * writer,const base::Value & value)261*635a8641SAndroid Build Coastguard Worker void AppendValueData(MessageWriter* writer, const base::Value& value) {
262*635a8641SAndroid Build Coastguard Worker   switch (value.type()) {
263*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::DICTIONARY: {
264*635a8641SAndroid Build Coastguard Worker       const base::DictionaryValue* dictionary = nullptr;
265*635a8641SAndroid Build Coastguard Worker       value.GetAsDictionary(&dictionary);
266*635a8641SAndroid Build Coastguard Worker       dbus::MessageWriter array_writer(nullptr);
267*635a8641SAndroid Build Coastguard Worker       writer->OpenArray("{sv}", &array_writer);
268*635a8641SAndroid Build Coastguard Worker       for (base::DictionaryValue::Iterator iter(*dictionary);
269*635a8641SAndroid Build Coastguard Worker            !iter.IsAtEnd(); iter.Advance()) {
270*635a8641SAndroid Build Coastguard Worker         dbus::MessageWriter dict_entry_writer(nullptr);
271*635a8641SAndroid Build Coastguard Worker         array_writer.OpenDictEntry(&dict_entry_writer);
272*635a8641SAndroid Build Coastguard Worker         dict_entry_writer.AppendString(iter.key());
273*635a8641SAndroid Build Coastguard Worker         AppendValueDataAsVariant(&dict_entry_writer, iter.value());
274*635a8641SAndroid Build Coastguard Worker         array_writer.CloseContainer(&dict_entry_writer);
275*635a8641SAndroid Build Coastguard Worker       }
276*635a8641SAndroid Build Coastguard Worker       writer->CloseContainer(&array_writer);
277*635a8641SAndroid Build Coastguard Worker       break;
278*635a8641SAndroid Build Coastguard Worker     }
279*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::LIST: {
280*635a8641SAndroid Build Coastguard Worker       const base::ListValue* list = nullptr;
281*635a8641SAndroid Build Coastguard Worker       value.GetAsList(&list);
282*635a8641SAndroid Build Coastguard Worker       dbus::MessageWriter array_writer(nullptr);
283*635a8641SAndroid Build Coastguard Worker       writer->OpenArray("v", &array_writer);
284*635a8641SAndroid Build Coastguard Worker       for (const auto& value : *list) {
285*635a8641SAndroid Build Coastguard Worker         AppendValueDataAsVariant(&array_writer, value);
286*635a8641SAndroid Build Coastguard Worker       }
287*635a8641SAndroid Build Coastguard Worker       writer->CloseContainer(&array_writer);
288*635a8641SAndroid Build Coastguard Worker       break;
289*635a8641SAndroid Build Coastguard Worker     }
290*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::BOOLEAN:
291*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::INTEGER:
292*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::DOUBLE:
293*635a8641SAndroid Build Coastguard Worker     case base::Value::Type::STRING:
294*635a8641SAndroid Build Coastguard Worker       AppendBasicTypeValueData(writer, value);
295*635a8641SAndroid Build Coastguard Worker       break;
296*635a8641SAndroid Build Coastguard Worker     default:
297*635a8641SAndroid Build Coastguard Worker       DLOG(ERROR) << "Unexpected type: " << value.type();
298*635a8641SAndroid Build Coastguard Worker   }
299*635a8641SAndroid Build Coastguard Worker }
300*635a8641SAndroid Build Coastguard Worker 
AppendValueDataAsVariant(MessageWriter * writer,const base::Value & value)301*635a8641SAndroid Build Coastguard Worker void AppendValueDataAsVariant(MessageWriter* writer, const base::Value& value) {
302*635a8641SAndroid Build Coastguard Worker   MessageWriter variant_writer(nullptr);
303*635a8641SAndroid Build Coastguard Worker   writer->OpenVariant(GetTypeSignature(value), &variant_writer);
304*635a8641SAndroid Build Coastguard Worker   AppendValueData(&variant_writer, value);
305*635a8641SAndroid Build Coastguard Worker   writer->CloseContainer(&variant_writer);
306*635a8641SAndroid Build Coastguard Worker }
307*635a8641SAndroid Build Coastguard Worker 
308*635a8641SAndroid Build Coastguard Worker }  // namespace dbus
309