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 #include "dumpsys/reflection_schema.h"
18 #include <string>
19 #include "bundler_generated.h"
20 #include "flatbuffers/flatbuffers.h"
21 #include "flatbuffers/idl.h"
22 #include "os/log.h"
23 
24 using namespace bluetooth;
25 
ReflectionSchema(const std::string & pre_bundled_schema)26 dumpsys::ReflectionSchema::ReflectionSchema(const std::string& pre_bundled_schema)
27     : pre_bundled_schema_(pre_bundled_schema) {
28   bundled_schema_ = flatbuffers::GetRoot<bluetooth::dumpsys::BundledSchema>(pre_bundled_schema_.data());
29   ASSERT(bundled_schema_ != nullptr);
30 }
31 
GetNumberOfBundledSchemas() const32 int dumpsys::ReflectionSchema::GetNumberOfBundledSchemas() const {
33   return bundled_schema_->map()->size();
34 }
35 
GetTitle() const36 std::string dumpsys::ReflectionSchema::GetTitle() const {
37   return bundled_schema_->title()->str();
38 }
39 
GetRootName() const40 std::string dumpsys::ReflectionSchema::GetRootName() const {
41   return bundled_schema_->root_name()->str();
42 }
43 
GetRootReflectionSchema() const44 const reflection::Schema* dumpsys::ReflectionSchema::GetRootReflectionSchema() const {
45   return FindInReflectionSchema(GetRootName());
46 }
47 
FindInReflectionSchema(const std::string & name) const48 const reflection::Schema* dumpsys::ReflectionSchema::FindInReflectionSchema(const std::string& name) const {
49   const flatbuffers::Vector<flatbuffers::Offset<bluetooth::dumpsys::BundledSchemaMap>>* map = bundled_schema_->map();
50 
51   for (auto it = map->cbegin(); it != map->cend(); ++it) {
52     if (it->name()->str() == name) {
53       flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(it->data()->Data()), it->data()->size());
54       if (!reflection::VerifySchemaBuffer(verifier)) {
55         LOG_WARN("Unable to verify schema buffer name:%s", name.c_str());
56         return nullptr;
57       }
58       return reflection::GetSchema(it->data()->Data());
59     }
60   }
61   return nullptr;
62 }
63 
PrintReflectionSchema() const64 void dumpsys::ReflectionSchema::PrintReflectionSchema() const {
65   const flatbuffers::Vector<flatbuffers::Offset<bluetooth::dumpsys::BundledSchemaMap>>* map = bundled_schema_->map();
66   LOG_INFO(
67       "  Bundled schema title:%s root_name:%s",
68       bundled_schema_->title()->c_str(),
69       bundled_schema_->root_name()->c_str());
70   for (auto it = map->cbegin(); it != map->cend(); ++it) {
71     LOG_INFO("    schema:%s", it->name()->c_str());
72   }
73 }
74 
VerifyReflectionSchema() const75 bool dumpsys::ReflectionSchema::VerifyReflectionSchema() const {
76   const flatbuffers::Vector<flatbuffers::Offset<bluetooth::dumpsys::BundledSchemaMap>>* map = bundled_schema_->map();
77 
78   for (auto it = map->cbegin(); it != map->cend(); ++it) {
79     flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t*>(it->data()->Data()), it->data()->size());
80     if (!reflection::VerifySchemaBuffer(verifier)) {
81       return false;
82     }
83   }
84   return true;
85 }
86