1*b9df5ad1SAndroid Build Coastguard Worker# 2*b9df5ad1SAndroid Build Coastguard Worker# Copyright (C) 2012 The Android Open Source Project 3*b9df5ad1SAndroid Build Coastguard Worker# 4*b9df5ad1SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*b9df5ad1SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*b9df5ad1SAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*b9df5ad1SAndroid Build Coastguard Worker# 8*b9df5ad1SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*b9df5ad1SAndroid Build Coastguard Worker# 10*b9df5ad1SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*b9df5ad1SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*b9df5ad1SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*b9df5ad1SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*b9df5ad1SAndroid Build Coastguard Worker# limitations under the License. 15*b9df5ad1SAndroid Build Coastguard Worker# 16*b9df5ad1SAndroid Build Coastguard Worker 17*b9df5ad1SAndroid Build Coastguard Worker""" 18*b9df5ad1SAndroid Build Coastguard WorkerA set of helpers for rendering Mako templates with a Metadata model. 19*b9df5ad1SAndroid Build Coastguard Worker""" 20*b9df5ad1SAndroid Build Coastguard Worker 21*b9df5ad1SAndroid Build Coastguard Workerimport metadata_model 22*b9df5ad1SAndroid Build Coastguard Workerimport re 23*b9df5ad1SAndroid Build Coastguard Workerimport markdown 24*b9df5ad1SAndroid Build Coastguard Workerimport textwrap 25*b9df5ad1SAndroid Build Coastguard Workerimport sys 26*b9df5ad1SAndroid Build Coastguard Workerimport bs4 27*b9df5ad1SAndroid Build Coastguard Worker# Monkey-patch BS4. WBR element must not have an end tag. 28*b9df5ad1SAndroid Build Coastguard Workerbs4.builder.HTMLTreeBuilder.empty_element_tags.add("wbr") 29*b9df5ad1SAndroid Build Coastguard Worker 30*b9df5ad1SAndroid Build Coastguard Workerfrom collections import OrderedDict, defaultdict 31*b9df5ad1SAndroid Build Coastguard Workerfrom operator import itemgetter 32*b9df5ad1SAndroid Build Coastguard Workerfrom os import path 33*b9df5ad1SAndroid Build Coastguard Worker 34*b9df5ad1SAndroid Build Coastguard Worker# Relative path from HTML file to the base directory used by <img> tags 35*b9df5ad1SAndroid Build Coastguard WorkerIMAGE_SRC_METADATA="images/camera2/metadata/" 36*b9df5ad1SAndroid Build Coastguard Worker 37*b9df5ad1SAndroid Build Coastguard Worker# Prepend this path to each <img src="foo"> in javadocs 38*b9df5ad1SAndroid Build Coastguard WorkerJAVADOC_IMAGE_SRC_METADATA="/reference/" + IMAGE_SRC_METADATA 39*b9df5ad1SAndroid Build Coastguard WorkerNDKDOC_IMAGE_SRC_METADATA="../" + IMAGE_SRC_METADATA 40*b9df5ad1SAndroid Build Coastguard Worker 41*b9df5ad1SAndroid Build Coastguard Worker#Corresponds to Android Q, where the camera VNDK was added (minor version 4 and vndk version 29). 42*b9df5ad1SAndroid Build Coastguard Worker# Minor version and vndk version must correspond to the same release 43*b9df5ad1SAndroid Build Coastguard WorkerFRAMEWORK_CAMERA_VNDK_HAL_MINOR_VERSION = 4 44*b9df5ad1SAndroid Build Coastguard WorkerFRAMEWORK_CAMERA_VNDK_STARTING_VERSION = 29 45*b9df5ad1SAndroid Build Coastguard Worker 46*b9df5ad1SAndroid Build Coastguard Worker_context_buf = None 47*b9df5ad1SAndroid Build Coastguard Worker_enum = None 48*b9df5ad1SAndroid Build Coastguard Worker 49*b9df5ad1SAndroid Build Coastguard Workerdef _is_sec_or_ins(x): 50*b9df5ad1SAndroid Build Coastguard Worker return isinstance(x, metadata_model.Section) or \ 51*b9df5ad1SAndroid Build Coastguard Worker isinstance(x, metadata_model.InnerNamespace) 52*b9df5ad1SAndroid Build Coastguard Worker 53*b9df5ad1SAndroid Build Coastguard Worker## 54*b9df5ad1SAndroid Build Coastguard Worker## Metadata Helpers 55*b9df5ad1SAndroid Build Coastguard Worker## 56*b9df5ad1SAndroid Build Coastguard Worker 57*b9df5ad1SAndroid Build Coastguard Workerdef find_all_sections(root): 58*b9df5ad1SAndroid Build Coastguard Worker """ 59*b9df5ad1SAndroid Build Coastguard Worker Find all descendants that are Section or InnerNamespace instances. 60*b9df5ad1SAndroid Build Coastguard Worker 61*b9df5ad1SAndroid Build Coastguard Worker Args: 62*b9df5ad1SAndroid Build Coastguard Worker root: a Metadata instance 63*b9df5ad1SAndroid Build Coastguard Worker 64*b9df5ad1SAndroid Build Coastguard Worker Returns: 65*b9df5ad1SAndroid Build Coastguard Worker A list of Section/InnerNamespace instances 66*b9df5ad1SAndroid Build Coastguard Worker 67*b9df5ad1SAndroid Build Coastguard Worker Remarks: 68*b9df5ad1SAndroid Build Coastguard Worker These are known as "sections" in the generated C code. 69*b9df5ad1SAndroid Build Coastguard Worker """ 70*b9df5ad1SAndroid Build Coastguard Worker return root.find_all(_is_sec_or_ins) 71*b9df5ad1SAndroid Build Coastguard Worker 72*b9df5ad1SAndroid Build Coastguard Workerdef find_all_sections_filtered(root, visibility): 73*b9df5ad1SAndroid Build Coastguard Worker """ 74*b9df5ad1SAndroid Build Coastguard Worker Find all descendants that are Section or InnerNamespace instances that do not 75*b9df5ad1SAndroid Build Coastguard Worker contain entries of the supplied visibility 76*b9df5ad1SAndroid Build Coastguard Worker 77*b9df5ad1SAndroid Build Coastguard Worker Args: 78*b9df5ad1SAndroid Build Coastguard Worker root: a Metadata instance 79*b9df5ad1SAndroid Build Coastguard Worker visibilities: An iterable of visibilities to filter against 80*b9df5ad1SAndroid Build Coastguard Worker 81*b9df5ad1SAndroid Build Coastguard Worker Returns: 82*b9df5ad1SAndroid Build Coastguard Worker A list of Section/InnerNamespace instances 83*b9df5ad1SAndroid Build Coastguard Worker 84*b9df5ad1SAndroid Build Coastguard Worker Remarks: 85*b9df5ad1SAndroid Build Coastguard Worker These are known as "sections" in the generated C code. 86*b9df5ad1SAndroid Build Coastguard Worker """ 87*b9df5ad1SAndroid Build Coastguard Worker sections = root.find_all(_is_sec_or_ins) 88*b9df5ad1SAndroid Build Coastguard Worker 89*b9df5ad1SAndroid Build Coastguard Worker filtered_sections = [] 90*b9df5ad1SAndroid Build Coastguard Worker for sec in sections: 91*b9df5ad1SAndroid Build Coastguard Worker if not any(filter_visibility(find_unique_entries(sec), visibility)): 92*b9df5ad1SAndroid Build Coastguard Worker filtered_sections.append(sec) 93*b9df5ad1SAndroid Build Coastguard Worker 94*b9df5ad1SAndroid Build Coastguard Worker return filtered_sections 95*b9df5ad1SAndroid Build Coastguard Worker 96*b9df5ad1SAndroid Build Coastguard Worker 97*b9df5ad1SAndroid Build Coastguard Workerdef find_parent_section(entry): 98*b9df5ad1SAndroid Build Coastguard Worker """ 99*b9df5ad1SAndroid Build Coastguard Worker Find the closest ancestor that is either a Section or InnerNamespace. 100*b9df5ad1SAndroid Build Coastguard Worker 101*b9df5ad1SAndroid Build Coastguard Worker Args: 102*b9df5ad1SAndroid Build Coastguard Worker entry: an Entry or Clone node 103*b9df5ad1SAndroid Build Coastguard Worker 104*b9df5ad1SAndroid Build Coastguard Worker Returns: 105*b9df5ad1SAndroid Build Coastguard Worker An instance of Section or InnerNamespace 106*b9df5ad1SAndroid Build Coastguard Worker """ 107*b9df5ad1SAndroid Build Coastguard Worker return entry.find_parent_first(_is_sec_or_ins) 108*b9df5ad1SAndroid Build Coastguard Worker 109*b9df5ad1SAndroid Build Coastguard Worker# find uniquely named entries (w/o recursing through inner namespaces) 110*b9df5ad1SAndroid Build Coastguard Workerdef find_unique_entries(node): 111*b9df5ad1SAndroid Build Coastguard Worker """ 112*b9df5ad1SAndroid Build Coastguard Worker Find all uniquely named entries, without recursing through inner namespaces. 113*b9df5ad1SAndroid Build Coastguard Worker 114*b9df5ad1SAndroid Build Coastguard Worker Args: 115*b9df5ad1SAndroid Build Coastguard Worker node: a Section or InnerNamespace instance 116*b9df5ad1SAndroid Build Coastguard Worker 117*b9df5ad1SAndroid Build Coastguard Worker Yields: 118*b9df5ad1SAndroid Build Coastguard Worker A sequence of MergedEntry nodes representing an entry 119*b9df5ad1SAndroid Build Coastguard Worker 120*b9df5ad1SAndroid Build Coastguard Worker Remarks: 121*b9df5ad1SAndroid Build Coastguard Worker This collapses multiple entries with the same fully qualified name into 122*b9df5ad1SAndroid Build Coastguard Worker one entry (e.g. if there are multiple entries in different kinds). 123*b9df5ad1SAndroid Build Coastguard Worker """ 124*b9df5ad1SAndroid Build Coastguard Worker if not isinstance(node, metadata_model.Section) and \ 125*b9df5ad1SAndroid Build Coastguard Worker not isinstance(node, metadata_model.InnerNamespace): 126*b9df5ad1SAndroid Build Coastguard Worker raise TypeError("expected node to be a Section or InnerNamespace") 127*b9df5ad1SAndroid Build Coastguard Worker 128*b9df5ad1SAndroid Build Coastguard Worker d = OrderedDict() 129*b9df5ad1SAndroid Build Coastguard Worker # remove the 'kinds' from the path between sec and the closest entries 130*b9df5ad1SAndroid Build Coastguard Worker # then search the immediate children of the search path 131*b9df5ad1SAndroid Build Coastguard Worker search_path = isinstance(node, metadata_model.Section) and node.kinds \ 132*b9df5ad1SAndroid Build Coastguard Worker or [node] 133*b9df5ad1SAndroid Build Coastguard Worker for i in search_path: 134*b9df5ad1SAndroid Build Coastguard Worker for entry in i.entries: 135*b9df5ad1SAndroid Build Coastguard Worker d[entry.name] = entry 136*b9df5ad1SAndroid Build Coastguard Worker 137*b9df5ad1SAndroid Build Coastguard Worker for k,v in d.items(): 138*b9df5ad1SAndroid Build Coastguard Worker yield v.merge() 139*b9df5ad1SAndroid Build Coastguard Worker 140*b9df5ad1SAndroid Build Coastguard Workerdef path_name(node): 141*b9df5ad1SAndroid Build Coastguard Worker """ 142*b9df5ad1SAndroid Build Coastguard Worker Calculate a period-separated string path from the root to this element, 143*b9df5ad1SAndroid Build Coastguard Worker by joining the names of each node and excluding the Metadata/Kind nodes 144*b9df5ad1SAndroid Build Coastguard Worker from the path. 145*b9df5ad1SAndroid Build Coastguard Worker 146*b9df5ad1SAndroid Build Coastguard Worker Args: 147*b9df5ad1SAndroid Build Coastguard Worker node: a Node instance 148*b9df5ad1SAndroid Build Coastguard Worker 149*b9df5ad1SAndroid Build Coastguard Worker Returns: 150*b9df5ad1SAndroid Build Coastguard Worker A string path 151*b9df5ad1SAndroid Build Coastguard Worker """ 152*b9df5ad1SAndroid Build Coastguard Worker 153*b9df5ad1SAndroid Build Coastguard Worker isa = lambda x,y: isinstance(x, y) 154*b9df5ad1SAndroid Build Coastguard Worker fltr = lambda x: not isa(x, metadata_model.Metadata) and \ 155*b9df5ad1SAndroid Build Coastguard Worker not isa(x, metadata_model.Kind) 156*b9df5ad1SAndroid Build Coastguard Worker 157*b9df5ad1SAndroid Build Coastguard Worker path = node.find_parents(fltr) 158*b9df5ad1SAndroid Build Coastguard Worker path = list(path) 159*b9df5ad1SAndroid Build Coastguard Worker path.reverse() 160*b9df5ad1SAndroid Build Coastguard Worker path.append(node) 161*b9df5ad1SAndroid Build Coastguard Worker 162*b9df5ad1SAndroid Build Coastguard Worker return ".".join((i.name for i in path)) 163*b9df5ad1SAndroid Build Coastguard Worker 164*b9df5ad1SAndroid Build Coastguard Workerdef ndk(name): 165*b9df5ad1SAndroid Build Coastguard Worker """ 166*b9df5ad1SAndroid Build Coastguard Worker Return the NDK version of given name, which replace 167*b9df5ad1SAndroid Build Coastguard Worker the leading "android" to "acamera" 168*b9df5ad1SAndroid Build Coastguard Worker 169*b9df5ad1SAndroid Build Coastguard Worker Args: 170*b9df5ad1SAndroid Build Coastguard Worker name: name string of an entry 171*b9df5ad1SAndroid Build Coastguard Worker 172*b9df5ad1SAndroid Build Coastguard Worker Returns: 173*b9df5ad1SAndroid Build Coastguard Worker A NDK version name string of the input name 174*b9df5ad1SAndroid Build Coastguard Worker """ 175*b9df5ad1SAndroid Build Coastguard Worker name_list = name.split(".") 176*b9df5ad1SAndroid Build Coastguard Worker if name_list[0] == "android": 177*b9df5ad1SAndroid Build Coastguard Worker name_list[0] = "acamera" 178*b9df5ad1SAndroid Build Coastguard Worker return ".".join(name_list) 179*b9df5ad1SAndroid Build Coastguard Worker 180*b9df5ad1SAndroid Build Coastguard Workerdef protobuf_type(entry): 181*b9df5ad1SAndroid Build Coastguard Worker """ 182*b9df5ad1SAndroid Build Coastguard Worker Return the protocol buffer message type for input metadata entry. 183*b9df5ad1SAndroid Build Coastguard Worker Only support types used by static metadata right now 184*b9df5ad1SAndroid Build Coastguard Worker 185*b9df5ad1SAndroid Build Coastguard Worker Returns: 186*b9df5ad1SAndroid Build Coastguard Worker A string of protocol buffer type. Ex: "optional int32" or "repeated RangeInt" 187*b9df5ad1SAndroid Build Coastguard Worker """ 188*b9df5ad1SAndroid Build Coastguard Worker typeName = None 189*b9df5ad1SAndroid Build Coastguard Worker if entry.typedef is None: 190*b9df5ad1SAndroid Build Coastguard Worker typeName = entry.type 191*b9df5ad1SAndroid Build Coastguard Worker else: 192*b9df5ad1SAndroid Build Coastguard Worker typeName = entry.typedef.name 193*b9df5ad1SAndroid Build Coastguard Worker 194*b9df5ad1SAndroid Build Coastguard Worker typename_to_protobuftype = { 195*b9df5ad1SAndroid Build Coastguard Worker "rational" : "Rational", 196*b9df5ad1SAndroid Build Coastguard Worker "size" : "Size", 197*b9df5ad1SAndroid Build Coastguard Worker "sizeF" : "SizeF", 198*b9df5ad1SAndroid Build Coastguard Worker "rectangle" : "Rect", 199*b9df5ad1SAndroid Build Coastguard Worker "streamConfigurationMap" : "StreamConfigurations", 200*b9df5ad1SAndroid Build Coastguard Worker "mandatoryStreamCombination" : "MandatoryStreamCombination", 201*b9df5ad1SAndroid Build Coastguard Worker "rangeInt" : "RangeInt", 202*b9df5ad1SAndroid Build Coastguard Worker "rangeLong" : "RangeLong", 203*b9df5ad1SAndroid Build Coastguard Worker "rangeFloat" : "RangeFloat", 204*b9df5ad1SAndroid Build Coastguard Worker "colorSpaceTransform" : "ColorSpaceTransform", 205*b9df5ad1SAndroid Build Coastguard Worker "blackLevelPattern" : "BlackLevelPattern", 206*b9df5ad1SAndroid Build Coastguard Worker "byte" : "int32", # protocol buffer don't support byte 207*b9df5ad1SAndroid Build Coastguard Worker "boolean" : "bool", 208*b9df5ad1SAndroid Build Coastguard Worker "float" : "float", 209*b9df5ad1SAndroid Build Coastguard Worker "double" : "double", 210*b9df5ad1SAndroid Build Coastguard Worker "int32" : "int32", 211*b9df5ad1SAndroid Build Coastguard Worker "int64" : "int64", 212*b9df5ad1SAndroid Build Coastguard Worker "enumList" : "int32", 213*b9df5ad1SAndroid Build Coastguard Worker "string" : "string", 214*b9df5ad1SAndroid Build Coastguard Worker "capability" : "Capability", 215*b9df5ad1SAndroid Build Coastguard Worker "multiResolutionStreamConfigurationMap" : "MultiResolutionStreamConfigurations", 216*b9df5ad1SAndroid Build Coastguard Worker "deviceStateSensorOrientationMap" : "DeviceStateSensorOrientationMap", 217*b9df5ad1SAndroid Build Coastguard Worker "dynamicRangeProfiles" : "DynamicRangeProfiles", 218*b9df5ad1SAndroid Build Coastguard Worker "colorSpaceProfiles" : "ColorSpaceProfiles", 219*b9df5ad1SAndroid Build Coastguard Worker "versionCode" : "int32", 220*b9df5ad1SAndroid Build Coastguard Worker "sharedSessionConfiguration" : "SharedSessionConfiguration", 221*b9df5ad1SAndroid Build Coastguard Worker } 222*b9df5ad1SAndroid Build Coastguard Worker 223*b9df5ad1SAndroid Build Coastguard Worker if typeName not in typename_to_protobuftype: 224*b9df5ad1SAndroid Build Coastguard Worker print(" ERROR: Could not find protocol buffer type for {%s} type {%s} typedef {%s}" % \ 225*b9df5ad1SAndroid Build Coastguard Worker (entry.name, entry.type, entry.typedef), file=sys.stderr) 226*b9df5ad1SAndroid Build Coastguard Worker 227*b9df5ad1SAndroid Build Coastguard Worker proto_type = typename_to_protobuftype[typeName] 228*b9df5ad1SAndroid Build Coastguard Worker 229*b9df5ad1SAndroid Build Coastguard Worker prefix = "optional" 230*b9df5ad1SAndroid Build Coastguard Worker if entry.container == 'array': 231*b9df5ad1SAndroid Build Coastguard Worker has_variable_size = False 232*b9df5ad1SAndroid Build Coastguard Worker for size in entry.container_sizes: 233*b9df5ad1SAndroid Build Coastguard Worker try: 234*b9df5ad1SAndroid Build Coastguard Worker size_int = int(size) 235*b9df5ad1SAndroid Build Coastguard Worker except ValueError: 236*b9df5ad1SAndroid Build Coastguard Worker has_variable_size = True 237*b9df5ad1SAndroid Build Coastguard Worker 238*b9df5ad1SAndroid Build Coastguard Worker if has_variable_size: 239*b9df5ad1SAndroid Build Coastguard Worker prefix = "repeated" 240*b9df5ad1SAndroid Build Coastguard Worker 241*b9df5ad1SAndroid Build Coastguard Worker return "%s %s" %(prefix, proto_type) 242*b9df5ad1SAndroid Build Coastguard Worker 243*b9df5ad1SAndroid Build Coastguard Worker 244*b9df5ad1SAndroid Build Coastguard Workerdef protobuf_name(entry): 245*b9df5ad1SAndroid Build Coastguard Worker """ 246*b9df5ad1SAndroid Build Coastguard Worker Return the protocol buffer field name for input metadata entry 247*b9df5ad1SAndroid Build Coastguard Worker 248*b9df5ad1SAndroid Build Coastguard Worker Returns: 249*b9df5ad1SAndroid Build Coastguard Worker A string. Ex: "android_colorCorrection_availableAberrationModes" 250*b9df5ad1SAndroid Build Coastguard Worker """ 251*b9df5ad1SAndroid Build Coastguard Worker return entry.name.replace(".", "_") 252*b9df5ad1SAndroid Build Coastguard Worker 253*b9df5ad1SAndroid Build Coastguard Workerdef has_descendants_with_enums(node): 254*b9df5ad1SAndroid Build Coastguard Worker """ 255*b9df5ad1SAndroid Build Coastguard Worker Determine whether or not the current node is or has any descendants with an 256*b9df5ad1SAndroid Build Coastguard Worker Enum node. 257*b9df5ad1SAndroid Build Coastguard Worker 258*b9df5ad1SAndroid Build Coastguard Worker Args: 259*b9df5ad1SAndroid Build Coastguard Worker node: a Node instance 260*b9df5ad1SAndroid Build Coastguard Worker 261*b9df5ad1SAndroid Build Coastguard Worker Returns: 262*b9df5ad1SAndroid Build Coastguard Worker True if it finds an Enum node in the subtree, False otherwise 263*b9df5ad1SAndroid Build Coastguard Worker """ 264*b9df5ad1SAndroid Build Coastguard Worker return bool(node.find_first(lambda x: isinstance(x, metadata_model.Enum))) 265*b9df5ad1SAndroid Build Coastguard Worker 266*b9df5ad1SAndroid Build Coastguard Workerdef get_children_by_throwing_away_kind(node, member='entries'): 267*b9df5ad1SAndroid Build Coastguard Worker """ 268*b9df5ad1SAndroid Build Coastguard Worker Get the children of this node by compressing the subtree together by removing 269*b9df5ad1SAndroid Build Coastguard Worker the kind and then combining any children nodes with the same name together. 270*b9df5ad1SAndroid Build Coastguard Worker 271*b9df5ad1SAndroid Build Coastguard Worker Args: 272*b9df5ad1SAndroid Build Coastguard Worker node: An instance of Section, InnerNamespace, or Kind 273*b9df5ad1SAndroid Build Coastguard Worker 274*b9df5ad1SAndroid Build Coastguard Worker Returns: 275*b9df5ad1SAndroid Build Coastguard Worker An iterable over the combined children of the subtree of node, 276*b9df5ad1SAndroid Build Coastguard Worker as if the Kinds never existed. 277*b9df5ad1SAndroid Build Coastguard Worker 278*b9df5ad1SAndroid Build Coastguard Worker Remarks: 279*b9df5ad1SAndroid Build Coastguard Worker Not recursive. Call this function repeatedly on each child. 280*b9df5ad1SAndroid Build Coastguard Worker """ 281*b9df5ad1SAndroid Build Coastguard Worker 282*b9df5ad1SAndroid Build Coastguard Worker if isinstance(node, metadata_model.Section): 283*b9df5ad1SAndroid Build Coastguard Worker # Note that this makes jump from Section to Kind, 284*b9df5ad1SAndroid Build Coastguard Worker # skipping the Kind entirely in the tree. 285*b9df5ad1SAndroid Build Coastguard Worker node_to_combine = node.combine_kinds_into_single_node() 286*b9df5ad1SAndroid Build Coastguard Worker else: 287*b9df5ad1SAndroid Build Coastguard Worker node_to_combine = node 288*b9df5ad1SAndroid Build Coastguard Worker 289*b9df5ad1SAndroid Build Coastguard Worker combined_kind = node_to_combine.combine_children_by_name() 290*b9df5ad1SAndroid Build Coastguard Worker 291*b9df5ad1SAndroid Build Coastguard Worker return (i for i in getattr(combined_kind, member)) 292*b9df5ad1SAndroid Build Coastguard Worker 293*b9df5ad1SAndroid Build Coastguard Workerdef get_children_by_filtering_kind(section, kind_name, member='entries'): 294*b9df5ad1SAndroid Build Coastguard Worker """ 295*b9df5ad1SAndroid Build Coastguard Worker Takes a section and yields the children of the merged kind under this section. 296*b9df5ad1SAndroid Build Coastguard Worker 297*b9df5ad1SAndroid Build Coastguard Worker Args: 298*b9df5ad1SAndroid Build Coastguard Worker section: An instance of Section 299*b9df5ad1SAndroid Build Coastguard Worker kind_name: A name of the kind, i.e. 'dynamic' or 'static' or 'controls' 300*b9df5ad1SAndroid Build Coastguard Worker 301*b9df5ad1SAndroid Build Coastguard Worker Returns: 302*b9df5ad1SAndroid Build Coastguard Worker An iterable over the children of the specified merged kind. 303*b9df5ad1SAndroid Build Coastguard Worker """ 304*b9df5ad1SAndroid Build Coastguard Worker 305*b9df5ad1SAndroid Build Coastguard Worker matched_kind = next((i for i in section.merged_kinds if i.name == kind_name), None) 306*b9df5ad1SAndroid Build Coastguard Worker 307*b9df5ad1SAndroid Build Coastguard Worker if matched_kind: 308*b9df5ad1SAndroid Build Coastguard Worker return getattr(matched_kind, member) 309*b9df5ad1SAndroid Build Coastguard Worker else: 310*b9df5ad1SAndroid Build Coastguard Worker return () 311*b9df5ad1SAndroid Build Coastguard Worker 312*b9df5ad1SAndroid Build Coastguard Worker## 313*b9df5ad1SAndroid Build Coastguard Worker## Filters 314*b9df5ad1SAndroid Build Coastguard Worker## 315*b9df5ad1SAndroid Build Coastguard Worker 316*b9df5ad1SAndroid Build Coastguard Worker# abcDef.xyz -> ABC_DEF_XYZ 317*b9df5ad1SAndroid Build Coastguard Workerdef csym(name): 318*b9df5ad1SAndroid Build Coastguard Worker """ 319*b9df5ad1SAndroid Build Coastguard Worker Convert an entry name string into an uppercase C symbol. 320*b9df5ad1SAndroid Build Coastguard Worker 321*b9df5ad1SAndroid Build Coastguard Worker Returns: 322*b9df5ad1SAndroid Build Coastguard Worker A string 323*b9df5ad1SAndroid Build Coastguard Worker 324*b9df5ad1SAndroid Build Coastguard Worker Example: 325*b9df5ad1SAndroid Build Coastguard Worker csym('abcDef.xyz') == 'ABC_DEF_XYZ' 326*b9df5ad1SAndroid Build Coastguard Worker """ 327*b9df5ad1SAndroid Build Coastguard Worker newstr = name 328*b9df5ad1SAndroid Build Coastguard Worker newstr = "".join([i.isupper() and ("_" + i) or i for i in newstr]).upper() 329*b9df5ad1SAndroid Build Coastguard Worker newstr = newstr.replace(".", "_") 330*b9df5ad1SAndroid Build Coastguard Worker return newstr 331*b9df5ad1SAndroid Build Coastguard Worker 332*b9df5ad1SAndroid Build Coastguard Worker# abcDef.xyz -> abc_def_xyz 333*b9df5ad1SAndroid Build Coastguard Workerdef csyml(name): 334*b9df5ad1SAndroid Build Coastguard Worker """ 335*b9df5ad1SAndroid Build Coastguard Worker Convert an entry name string into a lowercase C symbol. 336*b9df5ad1SAndroid Build Coastguard Worker 337*b9df5ad1SAndroid Build Coastguard Worker Returns: 338*b9df5ad1SAndroid Build Coastguard Worker A string 339*b9df5ad1SAndroid Build Coastguard Worker 340*b9df5ad1SAndroid Build Coastguard Worker Example: 341*b9df5ad1SAndroid Build Coastguard Worker csyml('abcDef.xyz') == 'abc_def_xyz' 342*b9df5ad1SAndroid Build Coastguard Worker """ 343*b9df5ad1SAndroid Build Coastguard Worker return csym(name).lower() 344*b9df5ad1SAndroid Build Coastguard Worker 345*b9df5ad1SAndroid Build Coastguard Worker# pad with spaces to make string len == size. add new line if too big 346*b9df5ad1SAndroid Build Coastguard Workerdef ljust(size, indent=4): 347*b9df5ad1SAndroid Build Coastguard Worker """ 348*b9df5ad1SAndroid Build Coastguard Worker Creates a function that given a string will pad it with spaces to make 349*b9df5ad1SAndroid Build Coastguard Worker the string length == size. Adds a new line if the string was too big. 350*b9df5ad1SAndroid Build Coastguard Worker 351*b9df5ad1SAndroid Build Coastguard Worker Args: 352*b9df5ad1SAndroid Build Coastguard Worker size: an integer representing how much spacing should be added 353*b9df5ad1SAndroid Build Coastguard Worker indent: an integer representing the initial indendation level 354*b9df5ad1SAndroid Build Coastguard Worker 355*b9df5ad1SAndroid Build Coastguard Worker Returns: 356*b9df5ad1SAndroid Build Coastguard Worker A function that takes a string and returns a string. 357*b9df5ad1SAndroid Build Coastguard Worker 358*b9df5ad1SAndroid Build Coastguard Worker Example: 359*b9df5ad1SAndroid Build Coastguard Worker ljust(8)("hello") == 'hello ' 360*b9df5ad1SAndroid Build Coastguard Worker 361*b9df5ad1SAndroid Build Coastguard Worker Remarks: 362*b9df5ad1SAndroid Build Coastguard Worker Deprecated. Use pad instead since it works for non-first items in a 363*b9df5ad1SAndroid Build Coastguard Worker Mako template. 364*b9df5ad1SAndroid Build Coastguard Worker """ 365*b9df5ad1SAndroid Build Coastguard Worker def inner(what): 366*b9df5ad1SAndroid Build Coastguard Worker newstr = what.ljust(size) 367*b9df5ad1SAndroid Build Coastguard Worker if len(newstr) > size: 368*b9df5ad1SAndroid Build Coastguard Worker return what + "\n" + "".ljust(indent + size) 369*b9df5ad1SAndroid Build Coastguard Worker else: 370*b9df5ad1SAndroid Build Coastguard Worker return newstr 371*b9df5ad1SAndroid Build Coastguard Worker return inner 372*b9df5ad1SAndroid Build Coastguard Worker 373*b9df5ad1SAndroid Build Coastguard Workerdef _find_new_line(): 374*b9df5ad1SAndroid Build Coastguard Worker 375*b9df5ad1SAndroid Build Coastguard Worker if _context_buf is None: 376*b9df5ad1SAndroid Build Coastguard Worker raise ValueError("Context buffer was not set") 377*b9df5ad1SAndroid Build Coastguard Worker 378*b9df5ad1SAndroid Build Coastguard Worker buf = _context_buf 379*b9df5ad1SAndroid Build Coastguard Worker x = -1 # since the first read is always '' 380*b9df5ad1SAndroid Build Coastguard Worker cur_pos = buf.tell() 381*b9df5ad1SAndroid Build Coastguard Worker while buf.tell() > 0 and buf.read(1) != '\n': 382*b9df5ad1SAndroid Build Coastguard Worker buf.seek(cur_pos - x) 383*b9df5ad1SAndroid Build Coastguard Worker x = x + 1 384*b9df5ad1SAndroid Build Coastguard Worker 385*b9df5ad1SAndroid Build Coastguard Worker buf.seek(cur_pos) 386*b9df5ad1SAndroid Build Coastguard Worker 387*b9df5ad1SAndroid Build Coastguard Worker return int(x) 388*b9df5ad1SAndroid Build Coastguard Worker 389*b9df5ad1SAndroid Build Coastguard Worker# Pad the string until the buffer reaches the desired column. 390*b9df5ad1SAndroid Build Coastguard Worker# If string is too long, insert a new line with 'col' spaces instead 391*b9df5ad1SAndroid Build Coastguard Workerdef pad(col): 392*b9df5ad1SAndroid Build Coastguard Worker """ 393*b9df5ad1SAndroid Build Coastguard Worker Create a function that given a string will pad it to the specified column col. 394*b9df5ad1SAndroid Build Coastguard Worker If the string overflows the column, put the string on a new line and pad it. 395*b9df5ad1SAndroid Build Coastguard Worker 396*b9df5ad1SAndroid Build Coastguard Worker Args: 397*b9df5ad1SAndroid Build Coastguard Worker col: an integer specifying the column number 398*b9df5ad1SAndroid Build Coastguard Worker 399*b9df5ad1SAndroid Build Coastguard Worker Returns: 400*b9df5ad1SAndroid Build Coastguard Worker A function that given a string will produce a padded string. 401*b9df5ad1SAndroid Build Coastguard Worker 402*b9df5ad1SAndroid Build Coastguard Worker Example: 403*b9df5ad1SAndroid Build Coastguard Worker pad(8)("hello") == 'hello ' 404*b9df5ad1SAndroid Build Coastguard Worker 405*b9df5ad1SAndroid Build Coastguard Worker Remarks: 406*b9df5ad1SAndroid Build Coastguard Worker This keeps track of the line written by Mako so far, so it will always 407*b9df5ad1SAndroid Build Coastguard Worker align to the column number correctly. 408*b9df5ad1SAndroid Build Coastguard Worker """ 409*b9df5ad1SAndroid Build Coastguard Worker def inner(what): 410*b9df5ad1SAndroid Build Coastguard Worker wut = int(col) 411*b9df5ad1SAndroid Build Coastguard Worker current_col = _find_new_line() 412*b9df5ad1SAndroid Build Coastguard Worker 413*b9df5ad1SAndroid Build Coastguard Worker if len(what) > wut - current_col: 414*b9df5ad1SAndroid Build Coastguard Worker return what + "\n".ljust(col) 415*b9df5ad1SAndroid Build Coastguard Worker else: 416*b9df5ad1SAndroid Build Coastguard Worker return what.ljust(wut - current_col) 417*b9df5ad1SAndroid Build Coastguard Worker return inner 418*b9df5ad1SAndroid Build Coastguard Worker 419*b9df5ad1SAndroid Build Coastguard Worker# int32 -> TYPE_INT32, byte -> TYPE_BYTE, etc. note that enum -> TYPE_INT32 420*b9df5ad1SAndroid Build Coastguard Workerdef ctype_enum(what): 421*b9df5ad1SAndroid Build Coastguard Worker """ 422*b9df5ad1SAndroid Build Coastguard Worker Generate a camera_metadata_type_t symbol from a type string. 423*b9df5ad1SAndroid Build Coastguard Worker 424*b9df5ad1SAndroid Build Coastguard Worker Args: 425*b9df5ad1SAndroid Build Coastguard Worker what: a type string 426*b9df5ad1SAndroid Build Coastguard Worker 427*b9df5ad1SAndroid Build Coastguard Worker Returns: 428*b9df5ad1SAndroid Build Coastguard Worker A string representing the camera_metadata_type_t 429*b9df5ad1SAndroid Build Coastguard Worker 430*b9df5ad1SAndroid Build Coastguard Worker Example: 431*b9df5ad1SAndroid Build Coastguard Worker ctype_enum('int32') == 'TYPE_INT32' 432*b9df5ad1SAndroid Build Coastguard Worker ctype_enum('int64') == 'TYPE_INT64' 433*b9df5ad1SAndroid Build Coastguard Worker ctype_enum('float') == 'TYPE_FLOAT' 434*b9df5ad1SAndroid Build Coastguard Worker 435*b9df5ad1SAndroid Build Coastguard Worker Remarks: 436*b9df5ad1SAndroid Build Coastguard Worker An enum is coerced to a byte since the rest of the camera_metadata 437*b9df5ad1SAndroid Build Coastguard Worker code doesn't support enums directly yet. 438*b9df5ad1SAndroid Build Coastguard Worker """ 439*b9df5ad1SAndroid Build Coastguard Worker return 'TYPE_%s' %(what.upper()) 440*b9df5ad1SAndroid Build Coastguard Worker 441*b9df5ad1SAndroid Build Coastguard Worker 442*b9df5ad1SAndroid Build Coastguard Worker# Calculate a java type name from an entry with a Typedef node 443*b9df5ad1SAndroid Build Coastguard Workerdef _jtypedef_type(entry): 444*b9df5ad1SAndroid Build Coastguard Worker typedef = entry.typedef 445*b9df5ad1SAndroid Build Coastguard Worker additional = '' 446*b9df5ad1SAndroid Build Coastguard Worker 447*b9df5ad1SAndroid Build Coastguard Worker # Hacky way to deal with arrays. Assume that if we have 448*b9df5ad1SAndroid Build Coastguard Worker # size 'Constant x N' the Constant is part of the Typedef size. 449*b9df5ad1SAndroid Build Coastguard Worker # So something sized just 'Constant', 'Constant1 x Constant2', etc 450*b9df5ad1SAndroid Build Coastguard Worker # is not treated as a real java array. 451*b9df5ad1SAndroid Build Coastguard Worker if entry.container == 'array': 452*b9df5ad1SAndroid Build Coastguard Worker has_variable_size = False 453*b9df5ad1SAndroid Build Coastguard Worker for size in entry.container_sizes: 454*b9df5ad1SAndroid Build Coastguard Worker try: 455*b9df5ad1SAndroid Build Coastguard Worker size_int = int(size) 456*b9df5ad1SAndroid Build Coastguard Worker except ValueError: 457*b9df5ad1SAndroid Build Coastguard Worker has_variable_size = True 458*b9df5ad1SAndroid Build Coastguard Worker 459*b9df5ad1SAndroid Build Coastguard Worker if has_variable_size: 460*b9df5ad1SAndroid Build Coastguard Worker additional = '[]' 461*b9df5ad1SAndroid Build Coastguard Worker 462*b9df5ad1SAndroid Build Coastguard Worker try: 463*b9df5ad1SAndroid Build Coastguard Worker name = typedef.languages['java'] 464*b9df5ad1SAndroid Build Coastguard Worker 465*b9df5ad1SAndroid Build Coastguard Worker return "%s%s" %(name, additional) 466*b9df5ad1SAndroid Build Coastguard Worker except KeyError: 467*b9df5ad1SAndroid Build Coastguard Worker return None 468*b9df5ad1SAndroid Build Coastguard Worker 469*b9df5ad1SAndroid Build Coastguard Worker# Box if primitive. Otherwise leave unboxed. 470*b9df5ad1SAndroid Build Coastguard Workerdef _jtype_box(type_name): 471*b9df5ad1SAndroid Build Coastguard Worker mapping = { 472*b9df5ad1SAndroid Build Coastguard Worker 'boolean': 'Boolean', 473*b9df5ad1SAndroid Build Coastguard Worker 'byte': 'Byte', 474*b9df5ad1SAndroid Build Coastguard Worker 'int': 'Integer', 475*b9df5ad1SAndroid Build Coastguard Worker 'float': 'Float', 476*b9df5ad1SAndroid Build Coastguard Worker 'double': 'Double', 477*b9df5ad1SAndroid Build Coastguard Worker 'long': 'Long' 478*b9df5ad1SAndroid Build Coastguard Worker } 479*b9df5ad1SAndroid Build Coastguard Worker 480*b9df5ad1SAndroid Build Coastguard Worker return mapping.get(type_name, type_name) 481*b9df5ad1SAndroid Build Coastguard Worker 482*b9df5ad1SAndroid Build Coastguard Workerdef jtype_unboxed(entry): 483*b9df5ad1SAndroid Build Coastguard Worker """ 484*b9df5ad1SAndroid Build Coastguard Worker Calculate the Java type from an entry type string, to be used whenever we 485*b9df5ad1SAndroid Build Coastguard Worker need the regular type in Java. It's not boxed, so it can't be used as a 486*b9df5ad1SAndroid Build Coastguard Worker generic type argument when the entry type happens to resolve to a primitive. 487*b9df5ad1SAndroid Build Coastguard Worker 488*b9df5ad1SAndroid Build Coastguard Worker Remarks: 489*b9df5ad1SAndroid Build Coastguard Worker Since Java generics cannot be instantiated with primitives, this version 490*b9df5ad1SAndroid Build Coastguard Worker is not applicable in that case. Use jtype_boxed instead for that. 491*b9df5ad1SAndroid Build Coastguard Worker 492*b9df5ad1SAndroid Build Coastguard Worker Returns: 493*b9df5ad1SAndroid Build Coastguard Worker The string representing the Java type. 494*b9df5ad1SAndroid Build Coastguard Worker """ 495*b9df5ad1SAndroid Build Coastguard Worker if not isinstance(entry, metadata_model.Entry): 496*b9df5ad1SAndroid Build Coastguard Worker raise ValueError("Expected entry to be an instance of Entry") 497*b9df5ad1SAndroid Build Coastguard Worker 498*b9df5ad1SAndroid Build Coastguard Worker metadata_type = entry.type 499*b9df5ad1SAndroid Build Coastguard Worker 500*b9df5ad1SAndroid Build Coastguard Worker java_type = None 501*b9df5ad1SAndroid Build Coastguard Worker 502*b9df5ad1SAndroid Build Coastguard Worker if entry.typedef: 503*b9df5ad1SAndroid Build Coastguard Worker typedef_name = _jtypedef_type(entry) 504*b9df5ad1SAndroid Build Coastguard Worker if typedef_name: 505*b9df5ad1SAndroid Build Coastguard Worker java_type = typedef_name # already takes into account arrays 506*b9df5ad1SAndroid Build Coastguard Worker 507*b9df5ad1SAndroid Build Coastguard Worker if not java_type: 508*b9df5ad1SAndroid Build Coastguard Worker if not java_type and entry.enum and metadata_type == 'byte': 509*b9df5ad1SAndroid Build Coastguard Worker # Always map byte enums to Java ints, unless there's a typedef override 510*b9df5ad1SAndroid Build Coastguard Worker base_type = 'int' 511*b9df5ad1SAndroid Build Coastguard Worker 512*b9df5ad1SAndroid Build Coastguard Worker else: 513*b9df5ad1SAndroid Build Coastguard Worker mapping = { 514*b9df5ad1SAndroid Build Coastguard Worker 'int32': 'int', 515*b9df5ad1SAndroid Build Coastguard Worker 'int64': 'long', 516*b9df5ad1SAndroid Build Coastguard Worker 'float': 'float', 517*b9df5ad1SAndroid Build Coastguard Worker 'double': 'double', 518*b9df5ad1SAndroid Build Coastguard Worker 'byte': 'byte', 519*b9df5ad1SAndroid Build Coastguard Worker 'rational': 'Rational' 520*b9df5ad1SAndroid Build Coastguard Worker } 521*b9df5ad1SAndroid Build Coastguard Worker 522*b9df5ad1SAndroid Build Coastguard Worker base_type = mapping[metadata_type] 523*b9df5ad1SAndroid Build Coastguard Worker 524*b9df5ad1SAndroid Build Coastguard Worker # Convert to array (enums, basic types) 525*b9df5ad1SAndroid Build Coastguard Worker if entry.container == 'array': 526*b9df5ad1SAndroid Build Coastguard Worker additional = '[]' 527*b9df5ad1SAndroid Build Coastguard Worker else: 528*b9df5ad1SAndroid Build Coastguard Worker additional = '' 529*b9df5ad1SAndroid Build Coastguard Worker 530*b9df5ad1SAndroid Build Coastguard Worker java_type = '%s%s' %(base_type, additional) 531*b9df5ad1SAndroid Build Coastguard Worker 532*b9df5ad1SAndroid Build Coastguard Worker # Now box this sucker. 533*b9df5ad1SAndroid Build Coastguard Worker return java_type 534*b9df5ad1SAndroid Build Coastguard Worker 535*b9df5ad1SAndroid Build Coastguard Workerdef jtype_boxed(entry): 536*b9df5ad1SAndroid Build Coastguard Worker """ 537*b9df5ad1SAndroid Build Coastguard Worker Calculate the Java type from an entry type string, to be used as a generic 538*b9df5ad1SAndroid Build Coastguard Worker type argument in Java. The type is guaranteed to inherit from Object. 539*b9df5ad1SAndroid Build Coastguard Worker 540*b9df5ad1SAndroid Build Coastguard Worker It will only box when absolutely necessary, i.e. int -> Integer[], but 541*b9df5ad1SAndroid Build Coastguard Worker int[] -> int[]. 542*b9df5ad1SAndroid Build Coastguard Worker 543*b9df5ad1SAndroid Build Coastguard Worker Remarks: 544*b9df5ad1SAndroid Build Coastguard Worker Since Java generics cannot be instantiated with primitives, this version 545*b9df5ad1SAndroid Build Coastguard Worker will use boxed types when absolutely required. 546*b9df5ad1SAndroid Build Coastguard Worker 547*b9df5ad1SAndroid Build Coastguard Worker Returns: 548*b9df5ad1SAndroid Build Coastguard Worker The string representing the boxed Java type. 549*b9df5ad1SAndroid Build Coastguard Worker """ 550*b9df5ad1SAndroid Build Coastguard Worker unboxed_type = jtype_unboxed(entry) 551*b9df5ad1SAndroid Build Coastguard Worker return _jtype_box(unboxed_type) 552*b9df5ad1SAndroid Build Coastguard Worker 553*b9df5ad1SAndroid Build Coastguard Workerdef _is_jtype_generic(entry): 554*b9df5ad1SAndroid Build Coastguard Worker """ 555*b9df5ad1SAndroid Build Coastguard Worker Determine whether or not the Java type represented by the entry type 556*b9df5ad1SAndroid Build Coastguard Worker string and/or typedef is a Java generic. 557*b9df5ad1SAndroid Build Coastguard Worker 558*b9df5ad1SAndroid Build Coastguard Worker For example, "Range<Integer>" would be considered a generic, whereas 559*b9df5ad1SAndroid Build Coastguard Worker a "MeteringRectangle" or a plain "Integer" would not be considered a generic. 560*b9df5ad1SAndroid Build Coastguard Worker 561*b9df5ad1SAndroid Build Coastguard Worker Args: 562*b9df5ad1SAndroid Build Coastguard Worker entry: An instance of an Entry node 563*b9df5ad1SAndroid Build Coastguard Worker 564*b9df5ad1SAndroid Build Coastguard Worker Returns: 565*b9df5ad1SAndroid Build Coastguard Worker True if it's a java generic, False otherwise. 566*b9df5ad1SAndroid Build Coastguard Worker """ 567*b9df5ad1SAndroid Build Coastguard Worker if entry.typedef: 568*b9df5ad1SAndroid Build Coastguard Worker local_typedef = _jtypedef_type(entry) 569*b9df5ad1SAndroid Build Coastguard Worker if local_typedef: 570*b9df5ad1SAndroid Build Coastguard Worker match = re.search(r'<.*>', local_typedef) 571*b9df5ad1SAndroid Build Coastguard Worker return bool(match) 572*b9df5ad1SAndroid Build Coastguard Worker return False 573*b9df5ad1SAndroid Build Coastguard Worker 574*b9df5ad1SAndroid Build Coastguard Workerdef _jtype_primitive(what): 575*b9df5ad1SAndroid Build Coastguard Worker """ 576*b9df5ad1SAndroid Build Coastguard Worker Calculate the Java type from an entry type string. 577*b9df5ad1SAndroid Build Coastguard Worker 578*b9df5ad1SAndroid Build Coastguard Worker Remarks: 579*b9df5ad1SAndroid Build Coastguard Worker Makes a special exception for Rational, since it's a primitive in terms of 580*b9df5ad1SAndroid Build Coastguard Worker the C-library camera_metadata type system. 581*b9df5ad1SAndroid Build Coastguard Worker 582*b9df5ad1SAndroid Build Coastguard Worker Returns: 583*b9df5ad1SAndroid Build Coastguard Worker The string representing the primitive type 584*b9df5ad1SAndroid Build Coastguard Worker """ 585*b9df5ad1SAndroid Build Coastguard Worker mapping = { 586*b9df5ad1SAndroid Build Coastguard Worker 'int32': 'int', 587*b9df5ad1SAndroid Build Coastguard Worker 'int64': 'long', 588*b9df5ad1SAndroid Build Coastguard Worker 'float': 'float', 589*b9df5ad1SAndroid Build Coastguard Worker 'double': 'double', 590*b9df5ad1SAndroid Build Coastguard Worker 'byte': 'byte', 591*b9df5ad1SAndroid Build Coastguard Worker 'rational': 'Rational' 592*b9df5ad1SAndroid Build Coastguard Worker } 593*b9df5ad1SAndroid Build Coastguard Worker 594*b9df5ad1SAndroid Build Coastguard Worker try: 595*b9df5ad1SAndroid Build Coastguard Worker return mapping[what] 596*b9df5ad1SAndroid Build Coastguard Worker except KeyError as e: 597*b9df5ad1SAndroid Build Coastguard Worker raise ValueError("Can't map '%s' to a primitive, not supported" %what) 598*b9df5ad1SAndroid Build Coastguard Worker 599*b9df5ad1SAndroid Build Coastguard Workerdef jclass(entry): 600*b9df5ad1SAndroid Build Coastguard Worker """ 601*b9df5ad1SAndroid Build Coastguard Worker Calculate the java Class reference string for an entry. 602*b9df5ad1SAndroid Build Coastguard Worker 603*b9df5ad1SAndroid Build Coastguard Worker Args: 604*b9df5ad1SAndroid Build Coastguard Worker entry: an Entry node 605*b9df5ad1SAndroid Build Coastguard Worker 606*b9df5ad1SAndroid Build Coastguard Worker Example: 607*b9df5ad1SAndroid Build Coastguard Worker <entry name="some_int" type="int32"/> 608*b9df5ad1SAndroid Build Coastguard Worker <entry name="some_int_array" type="int32" container='array'/> 609*b9df5ad1SAndroid Build Coastguard Worker 610*b9df5ad1SAndroid Build Coastguard Worker jclass(some_int) == 'int.class' 611*b9df5ad1SAndroid Build Coastguard Worker jclass(some_int_array) == 'int[].class' 612*b9df5ad1SAndroid Build Coastguard Worker 613*b9df5ad1SAndroid Build Coastguard Worker Returns: 614*b9df5ad1SAndroid Build Coastguard Worker The ClassName.class string 615*b9df5ad1SAndroid Build Coastguard Worker """ 616*b9df5ad1SAndroid Build Coastguard Worker 617*b9df5ad1SAndroid Build Coastguard Worker return "%s.class" %jtype_unboxed(entry) 618*b9df5ad1SAndroid Build Coastguard Worker 619*b9df5ad1SAndroid Build Coastguard Workerdef jkey_type_token(entry): 620*b9df5ad1SAndroid Build Coastguard Worker """ 621*b9df5ad1SAndroid Build Coastguard Worker Calculate the java type token compatible with a Key constructor. 622*b9df5ad1SAndroid Build Coastguard Worker This will be the Java Class<T> for non-generic classes, and a 623*b9df5ad1SAndroid Build Coastguard Worker TypeReference<T> for generic classes. 624*b9df5ad1SAndroid Build Coastguard Worker 625*b9df5ad1SAndroid Build Coastguard Worker Args: 626*b9df5ad1SAndroid Build Coastguard Worker entry: An entry node 627*b9df5ad1SAndroid Build Coastguard Worker 628*b9df5ad1SAndroid Build Coastguard Worker Returns: 629*b9df5ad1SAndroid Build Coastguard Worker The ClassName.class string, or 'new TypeReference<ClassName>() {{ }}' string 630*b9df5ad1SAndroid Build Coastguard Worker """ 631*b9df5ad1SAndroid Build Coastguard Worker if _is_jtype_generic(entry): 632*b9df5ad1SAndroid Build Coastguard Worker return "new TypeReference<%s>() {{ }}" %(jtype_boxed(entry)) 633*b9df5ad1SAndroid Build Coastguard Worker else: 634*b9df5ad1SAndroid Build Coastguard Worker return jclass(entry) 635*b9df5ad1SAndroid Build Coastguard Worker 636*b9df5ad1SAndroid Build Coastguard Workerdef jidentifier(what): 637*b9df5ad1SAndroid Build Coastguard Worker """ 638*b9df5ad1SAndroid Build Coastguard Worker Convert the input string into a valid Java identifier. 639*b9df5ad1SAndroid Build Coastguard Worker 640*b9df5ad1SAndroid Build Coastguard Worker Args: 641*b9df5ad1SAndroid Build Coastguard Worker what: any identifier string 642*b9df5ad1SAndroid Build Coastguard Worker 643*b9df5ad1SAndroid Build Coastguard Worker Returns: 644*b9df5ad1SAndroid Build Coastguard Worker String with added underscores if necessary. 645*b9df5ad1SAndroid Build Coastguard Worker """ 646*b9df5ad1SAndroid Build Coastguard Worker if re.match("\d", what): 647*b9df5ad1SAndroid Build Coastguard Worker return "_%s" %what 648*b9df5ad1SAndroid Build Coastguard Worker else: 649*b9df5ad1SAndroid Build Coastguard Worker return what 650*b9df5ad1SAndroid Build Coastguard Worker 651*b9df5ad1SAndroid Build Coastguard Workerdef enum_calculate_value_string(enum_value): 652*b9df5ad1SAndroid Build Coastguard Worker """ 653*b9df5ad1SAndroid Build Coastguard Worker Calculate the value of the enum, even if it does not have one explicitly 654*b9df5ad1SAndroid Build Coastguard Worker defined. 655*b9df5ad1SAndroid Build Coastguard Worker 656*b9df5ad1SAndroid Build Coastguard Worker This looks back for the first enum value that has a predefined value and then 657*b9df5ad1SAndroid Build Coastguard Worker applies addition until we get the right value, using C-enum semantics. 658*b9df5ad1SAndroid Build Coastguard Worker 659*b9df5ad1SAndroid Build Coastguard Worker Args: 660*b9df5ad1SAndroid Build Coastguard Worker enum_value: an EnumValue node with a valid Enum parent 661*b9df5ad1SAndroid Build Coastguard Worker 662*b9df5ad1SAndroid Build Coastguard Worker Example: 663*b9df5ad1SAndroid Build Coastguard Worker <enum> 664*b9df5ad1SAndroid Build Coastguard Worker <value>X</value> 665*b9df5ad1SAndroid Build Coastguard Worker <value id="5">Y</value> 666*b9df5ad1SAndroid Build Coastguard Worker <value>Z</value> 667*b9df5ad1SAndroid Build Coastguard Worker </enum> 668*b9df5ad1SAndroid Build Coastguard Worker 669*b9df5ad1SAndroid Build Coastguard Worker enum_calculate_value_string(X) == '0' 670*b9df5ad1SAndroid Build Coastguard Worker enum_calculate_Value_string(Y) == '5' 671*b9df5ad1SAndroid Build Coastguard Worker enum_calculate_value_string(Z) == '6' 672*b9df5ad1SAndroid Build Coastguard Worker 673*b9df5ad1SAndroid Build Coastguard Worker Returns: 674*b9df5ad1SAndroid Build Coastguard Worker String that represents the enum value as an integer literal. 675*b9df5ad1SAndroid Build Coastguard Worker """ 676*b9df5ad1SAndroid Build Coastguard Worker 677*b9df5ad1SAndroid Build Coastguard Worker enum_value_siblings = list(enum_value.parent.values) 678*b9df5ad1SAndroid Build Coastguard Worker this_index = enum_value_siblings.index(enum_value) 679*b9df5ad1SAndroid Build Coastguard Worker 680*b9df5ad1SAndroid Build Coastguard Worker def is_hex_string(instr): 681*b9df5ad1SAndroid Build Coastguard Worker return bool(re.match('0x[a-f0-9]+$', instr, re.IGNORECASE)) 682*b9df5ad1SAndroid Build Coastguard Worker 683*b9df5ad1SAndroid Build Coastguard Worker base_value = 0 684*b9df5ad1SAndroid Build Coastguard Worker base_offset = 0 685*b9df5ad1SAndroid Build Coastguard Worker emit_as_hex = False 686*b9df5ad1SAndroid Build Coastguard Worker 687*b9df5ad1SAndroid Build Coastguard Worker this_id = enum_value_siblings[this_index].id 688*b9df5ad1SAndroid Build Coastguard Worker while this_index != 0 and not this_id: 689*b9df5ad1SAndroid Build Coastguard Worker this_index -= 1 690*b9df5ad1SAndroid Build Coastguard Worker base_offset += 1 691*b9df5ad1SAndroid Build Coastguard Worker this_id = enum_value_siblings[this_index].id 692*b9df5ad1SAndroid Build Coastguard Worker 693*b9df5ad1SAndroid Build Coastguard Worker if this_id: 694*b9df5ad1SAndroid Build Coastguard Worker base_value = int(this_id, 0) # guess base 695*b9df5ad1SAndroid Build Coastguard Worker emit_as_hex = is_hex_string(this_id) 696*b9df5ad1SAndroid Build Coastguard Worker 697*b9df5ad1SAndroid Build Coastguard Worker if emit_as_hex: 698*b9df5ad1SAndroid Build Coastguard Worker return "0x%X" %(base_value + base_offset) 699*b9df5ad1SAndroid Build Coastguard Worker else: 700*b9df5ad1SAndroid Build Coastguard Worker return "%d" %(base_value + base_offset) 701*b9df5ad1SAndroid Build Coastguard Worker 702*b9df5ad1SAndroid Build Coastguard Workerdef enumerate_with_last(iterable): 703*b9df5ad1SAndroid Build Coastguard Worker """ 704*b9df5ad1SAndroid Build Coastguard Worker Enumerate a sequence of iterable, while knowing if this element is the last in 705*b9df5ad1SAndroid Build Coastguard Worker the sequence or not. 706*b9df5ad1SAndroid Build Coastguard Worker 707*b9df5ad1SAndroid Build Coastguard Worker Args: 708*b9df5ad1SAndroid Build Coastguard Worker iterable: an Iterable of some sequence 709*b9df5ad1SAndroid Build Coastguard Worker 710*b9df5ad1SAndroid Build Coastguard Worker Yields: 711*b9df5ad1SAndroid Build Coastguard Worker (element, bool) where the bool is True iff the element is last in the seq. 712*b9df5ad1SAndroid Build Coastguard Worker """ 713*b9df5ad1SAndroid Build Coastguard Worker it = (i for i in iterable) 714*b9df5ad1SAndroid Build Coastguard Worker 715*b9df5ad1SAndroid Build Coastguard Worker try: 716*b9df5ad1SAndroid Build Coastguard Worker first = next(it) # OK: raises exception if it is empty 717*b9df5ad1SAndroid Build Coastguard Worker except StopIteration: 718*b9df5ad1SAndroid Build Coastguard Worker return 719*b9df5ad1SAndroid Build Coastguard Worker 720*b9df5ad1SAndroid Build Coastguard Worker second = first # for when we have only 1 element in iterable 721*b9df5ad1SAndroid Build Coastguard Worker 722*b9df5ad1SAndroid Build Coastguard Worker try: 723*b9df5ad1SAndroid Build Coastguard Worker while True: 724*b9df5ad1SAndroid Build Coastguard Worker second = next(it) 725*b9df5ad1SAndroid Build Coastguard Worker # more elements remaining. 726*b9df5ad1SAndroid Build Coastguard Worker yield (first, False) 727*b9df5ad1SAndroid Build Coastguard Worker first = second 728*b9df5ad1SAndroid Build Coastguard Worker except StopIteration: 729*b9df5ad1SAndroid Build Coastguard Worker # last element. no more elements left 730*b9df5ad1SAndroid Build Coastguard Worker yield (second, True) 731*b9df5ad1SAndroid Build Coastguard Worker 732*b9df5ad1SAndroid Build Coastguard Workerdef pascal_case(what): 733*b9df5ad1SAndroid Build Coastguard Worker """ 734*b9df5ad1SAndroid Build Coastguard Worker Convert the first letter of a string to uppercase, to make the identifier 735*b9df5ad1SAndroid Build Coastguard Worker conform to PascalCase. 736*b9df5ad1SAndroid Build Coastguard Worker 737*b9df5ad1SAndroid Build Coastguard Worker If there are dots, remove the dots, and capitalize the letter following 738*b9df5ad1SAndroid Build Coastguard Worker where the dot was. Letters that weren't following dots are left unchanged, 739*b9df5ad1SAndroid Build Coastguard Worker except for the first letter of the string (which is made upper-case). 740*b9df5ad1SAndroid Build Coastguard Worker 741*b9df5ad1SAndroid Build Coastguard Worker Args: 742*b9df5ad1SAndroid Build Coastguard Worker what: a string representing some identifier 743*b9df5ad1SAndroid Build Coastguard Worker 744*b9df5ad1SAndroid Build Coastguard Worker Returns: 745*b9df5ad1SAndroid Build Coastguard Worker String with first letter capitalized 746*b9df5ad1SAndroid Build Coastguard Worker 747*b9df5ad1SAndroid Build Coastguard Worker Example: 748*b9df5ad1SAndroid Build Coastguard Worker pascal_case("helloWorld") == "HelloWorld" 749*b9df5ad1SAndroid Build Coastguard Worker pascal_case("foo") == "Foo" 750*b9df5ad1SAndroid Build Coastguard Worker pascal_case("hello.world") = "HelloWorld" 751*b9df5ad1SAndroid Build Coastguard Worker pascal_case("fooBar.fooBar") = "FooBarFooBar" 752*b9df5ad1SAndroid Build Coastguard Worker """ 753*b9df5ad1SAndroid Build Coastguard Worker return "".join([s[0:1].upper() + s[1:] for s in what.split('.')]) 754*b9df5ad1SAndroid Build Coastguard Worker 755*b9df5ad1SAndroid Build Coastguard Workerdef jkey_identifier(what): 756*b9df5ad1SAndroid Build Coastguard Worker """ 757*b9df5ad1SAndroid Build Coastguard Worker Return a Java identifier from a property name. 758*b9df5ad1SAndroid Build Coastguard Worker 759*b9df5ad1SAndroid Build Coastguard Worker Args: 760*b9df5ad1SAndroid Build Coastguard Worker what: a string representing a property name. 761*b9df5ad1SAndroid Build Coastguard Worker 762*b9df5ad1SAndroid Build Coastguard Worker Returns: 763*b9df5ad1SAndroid Build Coastguard Worker Java identifier corresponding to the property name. May need to be 764*b9df5ad1SAndroid Build Coastguard Worker prepended with the appropriate Java class name by the caller of this 765*b9df5ad1SAndroid Build Coastguard Worker function. Note that the outer namespace is stripped from the property 766*b9df5ad1SAndroid Build Coastguard Worker name. 767*b9df5ad1SAndroid Build Coastguard Worker 768*b9df5ad1SAndroid Build Coastguard Worker Example: 769*b9df5ad1SAndroid Build Coastguard Worker jkey_identifier("android.lens.facing") == "LENS_FACING" 770*b9df5ad1SAndroid Build Coastguard Worker """ 771*b9df5ad1SAndroid Build Coastguard Worker return csym(what[what.find('.') + 1:]) 772*b9df5ad1SAndroid Build Coastguard Worker 773*b9df5ad1SAndroid Build Coastguard Workerdef jenum_value(enum_entry, enum_value): 774*b9df5ad1SAndroid Build Coastguard Worker """ 775*b9df5ad1SAndroid Build Coastguard Worker Calculate the Java name for an integer enum value 776*b9df5ad1SAndroid Build Coastguard Worker 777*b9df5ad1SAndroid Build Coastguard Worker Args: 778*b9df5ad1SAndroid Build Coastguard Worker enum: An enum-typed Entry node 779*b9df5ad1SAndroid Build Coastguard Worker value: An EnumValue node for the enum 780*b9df5ad1SAndroid Build Coastguard Worker 781*b9df5ad1SAndroid Build Coastguard Worker Returns: 782*b9df5ad1SAndroid Build Coastguard Worker String representing the Java symbol 783*b9df5ad1SAndroid Build Coastguard Worker """ 784*b9df5ad1SAndroid Build Coastguard Worker 785*b9df5ad1SAndroid Build Coastguard Worker cname = csym(enum_entry.name) 786*b9df5ad1SAndroid Build Coastguard Worker return cname[cname.find('_') + 1:] + '_' + enum_value.name 787*b9df5ad1SAndroid Build Coastguard Worker 788*b9df5ad1SAndroid Build Coastguard Workerdef generate_extra_javadoc_detail(entry): 789*b9df5ad1SAndroid Build Coastguard Worker """ 790*b9df5ad1SAndroid Build Coastguard Worker Returns a function to add extra details for an entry into a string for inclusion into 791*b9df5ad1SAndroid Build Coastguard Worker javadoc. Adds information about units, the list of enum values for this key, and the valid 792*b9df5ad1SAndroid Build Coastguard Worker range. 793*b9df5ad1SAndroid Build Coastguard Worker """ 794*b9df5ad1SAndroid Build Coastguard Worker def inner(text): 795*b9df5ad1SAndroid Build Coastguard Worker if entry.units and not (entry.typedef and entry.typedef.name == 'string'): 796*b9df5ad1SAndroid Build Coastguard Worker text += '\n\n<b>Units</b>: %s\n' % (dedent(entry.units)) 797*b9df5ad1SAndroid Build Coastguard Worker if entry.enum and not (entry.typedef and entry.typedef.languages.get('java')): 798*b9df5ad1SAndroid Build Coastguard Worker text += '\n\n<b>Possible values:</b>\n<ul>\n' 799*b9df5ad1SAndroid Build Coastguard Worker for value in entry.enum.values: 800*b9df5ad1SAndroid Build Coastguard Worker if not value.hidden and (value.aconfig_flag == entry.aconfig_flag): 801*b9df5ad1SAndroid Build Coastguard Worker text += ' <li>{@link #%s %s}</li>\n' % ( jenum_value(entry, value ), value.name ) 802*b9df5ad1SAndroid Build Coastguard Worker text += '</ul>\n' 803*b9df5ad1SAndroid Build Coastguard Worker if entry.range: 804*b9df5ad1SAndroid Build Coastguard Worker if entry.enum and not (entry.typedef and entry.typedef.languages.get('java')): 805*b9df5ad1SAndroid Build Coastguard Worker text += '\n\n<b>Available values for this device:</b><br>\n' 806*b9df5ad1SAndroid Build Coastguard Worker else: 807*b9df5ad1SAndroid Build Coastguard Worker text += '\n\n<b>Range of valid values:</b><br>\n' 808*b9df5ad1SAndroid Build Coastguard Worker text += '%s\n' % (dedent(entry.range)) 809*b9df5ad1SAndroid Build Coastguard Worker if entry.hwlevel != 'legacy': # covers any of (None, 'limited', 'full') 810*b9df5ad1SAndroid Build Coastguard Worker text += '\n\n<b>Optional</b> - The value for this key may be {@code null} on some devices.\n' 811*b9df5ad1SAndroid Build Coastguard Worker if entry.hwlevel == 'full': 812*b9df5ad1SAndroid Build Coastguard Worker text += \ 813*b9df5ad1SAndroid Build Coastguard Worker '\n<b>Full capability</b> - \n' + \ 814*b9df5ad1SAndroid Build Coastguard Worker 'Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the\n' + \ 815*b9df5ad1SAndroid Build Coastguard Worker 'android.info.supportedHardwareLevel key\n' 816*b9df5ad1SAndroid Build Coastguard Worker if entry.hwlevel == 'limited': 817*b9df5ad1SAndroid Build Coastguard Worker text += \ 818*b9df5ad1SAndroid Build Coastguard Worker '\n<b>Limited capability</b> - \n' + \ 819*b9df5ad1SAndroid Build Coastguard Worker 'Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the\n' + \ 820*b9df5ad1SAndroid Build Coastguard Worker 'android.info.supportedHardwareLevel key\n' 821*b9df5ad1SAndroid Build Coastguard Worker if entry.hwlevel == 'legacy': 822*b9df5ad1SAndroid Build Coastguard Worker text += "\nThis key is available on all devices." 823*b9df5ad1SAndroid Build Coastguard Worker if entry.permission_needed == "true": 824*b9df5ad1SAndroid Build Coastguard Worker text += "\n\n<b>Permission {@link android.Manifest.permission#CAMERA} is needed to access this property</b>\n\n" 825*b9df5ad1SAndroid Build Coastguard Worker 826*b9df5ad1SAndroid Build Coastguard Worker return text 827*b9df5ad1SAndroid Build Coastguard Worker return inner 828*b9df5ad1SAndroid Build Coastguard Worker 829*b9df5ad1SAndroid Build Coastguard Worker 830*b9df5ad1SAndroid Build Coastguard Workerdef javadoc(metadata, indent = 4): 831*b9df5ad1SAndroid Build Coastguard Worker """ 832*b9df5ad1SAndroid Build Coastguard Worker Returns a function to format a markdown syntax text block as a 833*b9df5ad1SAndroid Build Coastguard Worker javadoc comment section, given a set of metadata 834*b9df5ad1SAndroid Build Coastguard Worker 835*b9df5ad1SAndroid Build Coastguard Worker Args: 836*b9df5ad1SAndroid Build Coastguard Worker metadata: A Metadata instance, representing the top-level root 837*b9df5ad1SAndroid Build Coastguard Worker of the metadata for cross-referencing 838*b9df5ad1SAndroid Build Coastguard Worker indent: baseline level of indentation for javadoc block 839*b9df5ad1SAndroid Build Coastguard Worker Returns: 840*b9df5ad1SAndroid Build Coastguard Worker A function that transforms a String text block as follows: 841*b9df5ad1SAndroid Build Coastguard Worker - Indent and * for insertion into a Javadoc comment block 842*b9df5ad1SAndroid Build Coastguard Worker - Trailing whitespace removed 843*b9df5ad1SAndroid Build Coastguard Worker - Entire body rendered via markdown to generate HTML 844*b9df5ad1SAndroid Build Coastguard Worker - All tag names converted to appropriate Javadoc {@link} with @see 845*b9df5ad1SAndroid Build Coastguard Worker for each tag 846*b9df5ad1SAndroid Build Coastguard Worker 847*b9df5ad1SAndroid Build Coastguard Worker Example: 848*b9df5ad1SAndroid Build Coastguard Worker "This is a comment for Javadoc\n" + 849*b9df5ad1SAndroid Build Coastguard Worker " with multiple lines, that should be \n" + 850*b9df5ad1SAndroid Build Coastguard Worker " formatted better\n" + 851*b9df5ad1SAndroid Build Coastguard Worker "\n" + 852*b9df5ad1SAndroid Build Coastguard Worker " That covers multiple lines as well\n" 853*b9df5ad1SAndroid Build Coastguard Worker " And references android.control.mode\n" 854*b9df5ad1SAndroid Build Coastguard Worker 855*b9df5ad1SAndroid Build Coastguard Worker transforms to 856*b9df5ad1SAndroid Build Coastguard Worker " * <p>This is a comment for Javadoc\n" + 857*b9df5ad1SAndroid Build Coastguard Worker " * with multiple lines, that should be\n" + 858*b9df5ad1SAndroid Build Coastguard Worker " * formatted better</p>\n" + 859*b9df5ad1SAndroid Build Coastguard Worker " * <p>That covers multiple lines as well</p>\n" + 860*b9df5ad1SAndroid Build Coastguard Worker " * and references {@link CaptureRequest#CONTROL_MODE android.control.mode}\n" + 861*b9df5ad1SAndroid Build Coastguard Worker " *\n" + 862*b9df5ad1SAndroid Build Coastguard Worker " * @see CaptureRequest#CONTROL_MODE\n" 863*b9df5ad1SAndroid Build Coastguard Worker """ 864*b9df5ad1SAndroid Build Coastguard Worker def javadoc_formatter(text): 865*b9df5ad1SAndroid Build Coastguard Worker comment_prefix = " " * indent + " * " 866*b9df5ad1SAndroid Build Coastguard Worker 867*b9df5ad1SAndroid Build Coastguard Worker # render with markdown => HTML 868*b9df5ad1SAndroid Build Coastguard Worker javatext = md(text, JAVADOC_IMAGE_SRC_METADATA) 869*b9df5ad1SAndroid Build Coastguard Worker 870*b9df5ad1SAndroid Build Coastguard Worker # Identity transform for javadoc links 871*b9df5ad1SAndroid Build Coastguard Worker def javadoc_link_filter(target, target_ndk, shortname): 872*b9df5ad1SAndroid Build Coastguard Worker return '{@link %s %s}' % (target, shortname) 873*b9df5ad1SAndroid Build Coastguard Worker 874*b9df5ad1SAndroid Build Coastguard Worker javatext = filter_links(javatext, javadoc_link_filter) 875*b9df5ad1SAndroid Build Coastguard Worker 876*b9df5ad1SAndroid Build Coastguard Worker # Crossref tag names 877*b9df5ad1SAndroid Build Coastguard Worker kind_mapping = { 878*b9df5ad1SAndroid Build Coastguard Worker 'static': 'CameraCharacteristics', 879*b9df5ad1SAndroid Build Coastguard Worker 'dynamic': 'CaptureResult', 880*b9df5ad1SAndroid Build Coastguard Worker 'controls': 'CaptureRequest' } 881*b9df5ad1SAndroid Build Coastguard Worker 882*b9df5ad1SAndroid Build Coastguard Worker # Convert metadata entry "android.x.y.z" to form 883*b9df5ad1SAndroid Build Coastguard Worker # "{@link CaptureRequest#X_Y_Z android.x.y.z}" 884*b9df5ad1SAndroid Build Coastguard Worker def javadoc_crossref_filter(node): 885*b9df5ad1SAndroid Build Coastguard Worker if node.applied_visibility in ('public', 'java_public', 'fwk_java_public', 'fwk_public',\ 886*b9df5ad1SAndroid Build Coastguard Worker 'fwk_system_public'): 887*b9df5ad1SAndroid Build Coastguard Worker return '{@link %s#%s %s}' % (kind_mapping[node.kind], 888*b9df5ad1SAndroid Build Coastguard Worker jkey_identifier(node.name), 889*b9df5ad1SAndroid Build Coastguard Worker node.name) 890*b9df5ad1SAndroid Build Coastguard Worker else: 891*b9df5ad1SAndroid Build Coastguard Worker return node.name 892*b9df5ad1SAndroid Build Coastguard Worker 893*b9df5ad1SAndroid Build Coastguard Worker # For each public tag "android.x.y.z" referenced, add a 894*b9df5ad1SAndroid Build Coastguard Worker # "@see CaptureRequest#X_Y_Z" 895*b9df5ad1SAndroid Build Coastguard Worker def javadoc_crossref_see_filter(node_set): 896*b9df5ad1SAndroid Build Coastguard Worker node_set = (x for x in node_set if x.applied_visibility in \ 897*b9df5ad1SAndroid Build Coastguard Worker ('public', 'java_public', 'fwk_java_public', 'fwk_public', 'fwk_system_public')) 898*b9df5ad1SAndroid Build Coastguard Worker 899*b9df5ad1SAndroid Build Coastguard Worker text = '\n' 900*b9df5ad1SAndroid Build Coastguard Worker for node in node_set: 901*b9df5ad1SAndroid Build Coastguard Worker text = text + '\n@see %s#%s' % (kind_mapping[node.kind], 902*b9df5ad1SAndroid Build Coastguard Worker jkey_identifier(node.name)) 903*b9df5ad1SAndroid Build Coastguard Worker 904*b9df5ad1SAndroid Build Coastguard Worker return text if text != '\n' else '' 905*b9df5ad1SAndroid Build Coastguard Worker 906*b9df5ad1SAndroid Build Coastguard Worker javatext = filter_tags(javatext, metadata, javadoc_crossref_filter, javadoc_crossref_see_filter) 907*b9df5ad1SAndroid Build Coastguard Worker 908*b9df5ad1SAndroid Build Coastguard Worker def line_filter(line): 909*b9df5ad1SAndroid Build Coastguard Worker # Indent each line 910*b9df5ad1SAndroid Build Coastguard Worker # Add ' * ' to it for stylistic reasons 911*b9df5ad1SAndroid Build Coastguard Worker # Strip right side of trailing whitespace 912*b9df5ad1SAndroid Build Coastguard Worker return (comment_prefix + line).rstrip() 913*b9df5ad1SAndroid Build Coastguard Worker 914*b9df5ad1SAndroid Build Coastguard Worker # Process each line with above filter 915*b9df5ad1SAndroid Build Coastguard Worker javatext = "\n".join(line_filter(i) for i in javatext.split("\n")) + "\n" 916*b9df5ad1SAndroid Build Coastguard Worker 917*b9df5ad1SAndroid Build Coastguard Worker return javatext 918*b9df5ad1SAndroid Build Coastguard Worker 919*b9df5ad1SAndroid Build Coastguard Worker return javadoc_formatter 920*b9df5ad1SAndroid Build Coastguard Worker 921*b9df5ad1SAndroid Build Coastguard Workerdef ndkdoc(metadata, indent = 4): 922*b9df5ad1SAndroid Build Coastguard Worker """ 923*b9df5ad1SAndroid Build Coastguard Worker Returns a function to format a markdown syntax text block as a 924*b9df5ad1SAndroid Build Coastguard Worker NDK camera API C/C++ comment section, given a set of metadata 925*b9df5ad1SAndroid Build Coastguard Worker 926*b9df5ad1SAndroid Build Coastguard Worker Args: 927*b9df5ad1SAndroid Build Coastguard Worker metadata: A Metadata instance, representing the top-level root 928*b9df5ad1SAndroid Build Coastguard Worker of the metadata for cross-referencing 929*b9df5ad1SAndroid Build Coastguard Worker indent: baseline level of indentation for comment block 930*b9df5ad1SAndroid Build Coastguard Worker Returns: 931*b9df5ad1SAndroid Build Coastguard Worker A function that transforms a String text block as follows: 932*b9df5ad1SAndroid Build Coastguard Worker - Indent and * for insertion into a comment block 933*b9df5ad1SAndroid Build Coastguard Worker - Trailing whitespace removed 934*b9df5ad1SAndroid Build Coastguard Worker - Entire body rendered via markdown 935*b9df5ad1SAndroid Build Coastguard Worker - All tag names converted to appropriate NDK tag name for each tag 936*b9df5ad1SAndroid Build Coastguard Worker 937*b9df5ad1SAndroid Build Coastguard Worker Example: 938*b9df5ad1SAndroid Build Coastguard Worker "This is a comment for NDK\n" + 939*b9df5ad1SAndroid Build Coastguard Worker " with multiple lines, that should be \n" + 940*b9df5ad1SAndroid Build Coastguard Worker " formatted better\n" + 941*b9df5ad1SAndroid Build Coastguard Worker "\n" + 942*b9df5ad1SAndroid Build Coastguard Worker " That covers multiple lines as well\n" 943*b9df5ad1SAndroid Build Coastguard Worker " And references android.control.mode\n" 944*b9df5ad1SAndroid Build Coastguard Worker 945*b9df5ad1SAndroid Build Coastguard Worker transforms to 946*b9df5ad1SAndroid Build Coastguard Worker " * This is a comment for NDK\n" + 947*b9df5ad1SAndroid Build Coastguard Worker " * with multiple lines, that should be\n" + 948*b9df5ad1SAndroid Build Coastguard Worker " * formatted better\n" + 949*b9df5ad1SAndroid Build Coastguard Worker " * That covers multiple lines as well\n" + 950*b9df5ad1SAndroid Build Coastguard Worker " * and references ACAMERA_CONTROL_MODE\n" + 951*b9df5ad1SAndroid Build Coastguard Worker " *\n" + 952*b9df5ad1SAndroid Build Coastguard Worker " * @see ACAMERA_CONTROL_MODE\n" 953*b9df5ad1SAndroid Build Coastguard Worker """ 954*b9df5ad1SAndroid Build Coastguard Worker def ndkdoc_formatter(text): 955*b9df5ad1SAndroid Build Coastguard Worker # render with markdown => HTML 956*b9df5ad1SAndroid Build Coastguard Worker # Turn off the table plugin since doxygen doesn't recognize generated <thead> <tbody> tags 957*b9df5ad1SAndroid Build Coastguard Worker ndktext = md(text, NDKDOC_IMAGE_SRC_METADATA, False) 958*b9df5ad1SAndroid Build Coastguard Worker 959*b9df5ad1SAndroid Build Coastguard Worker # Simple transform for ndk doc links 960*b9df5ad1SAndroid Build Coastguard Worker def ndkdoc_link_filter(target, target_ndk, shortname): 961*b9df5ad1SAndroid Build Coastguard Worker if target_ndk is not None: 962*b9df5ad1SAndroid Build Coastguard Worker return '{@link %s %s}' % (target_ndk, shortname) 963*b9df5ad1SAndroid Build Coastguard Worker 964*b9df5ad1SAndroid Build Coastguard Worker # Create HTML link to Javadoc 965*b9df5ad1SAndroid Build Coastguard Worker if shortname == '': 966*b9df5ad1SAndroid Build Coastguard Worker lastdot = target.rfind('.') 967*b9df5ad1SAndroid Build Coastguard Worker if lastdot == -1: 968*b9df5ad1SAndroid Build Coastguard Worker shortname = target 969*b9df5ad1SAndroid Build Coastguard Worker else: 970*b9df5ad1SAndroid Build Coastguard Worker shortname = target[lastdot + 1:] 971*b9df5ad1SAndroid Build Coastguard Worker 972*b9df5ad1SAndroid Build Coastguard Worker target = target.replace('.','/') 973*b9df5ad1SAndroid Build Coastguard Worker if target.find('#') != -1: 974*b9df5ad1SAndroid Build Coastguard Worker target = target.replace('#','.html#') 975*b9df5ad1SAndroid Build Coastguard Worker else: 976*b9df5ad1SAndroid Build Coastguard Worker target = target + '.html' 977*b9df5ad1SAndroid Build Coastguard Worker 978*b9df5ad1SAndroid Build Coastguard Worker # Work around html links with inner classes. 979*b9df5ad1SAndroid Build Coastguard Worker target = target.replace('CaptureRequest/Builder', 'CaptureRequest.Builder') 980*b9df5ad1SAndroid Build Coastguard Worker target = target.replace('Build/VERSION', 'Build.VERSION') 981*b9df5ad1SAndroid Build Coastguard Worker 982*b9df5ad1SAndroid Build Coastguard Worker return '<a href="https://developer.android.com/reference/%s">%s</a>' % (target, shortname) 983*b9df5ad1SAndroid Build Coastguard Worker 984*b9df5ad1SAndroid Build Coastguard Worker ndktext = filter_links(ndktext, ndkdoc_link_filter) 985*b9df5ad1SAndroid Build Coastguard Worker 986*b9df5ad1SAndroid Build Coastguard Worker # Convert metadata entry "android.x.y.z" to form 987*b9df5ad1SAndroid Build Coastguard Worker # NDK tag format of "ACAMERA_X_Y_Z" 988*b9df5ad1SAndroid Build Coastguard Worker def ndkdoc_crossref_filter(node): 989*b9df5ad1SAndroid Build Coastguard Worker if node.applied_ndk_visible == 'true': 990*b9df5ad1SAndroid Build Coastguard Worker return csym(ndk(node.name)) 991*b9df5ad1SAndroid Build Coastguard Worker else: 992*b9df5ad1SAndroid Build Coastguard Worker return node.name 993*b9df5ad1SAndroid Build Coastguard Worker 994*b9df5ad1SAndroid Build Coastguard Worker # For each public tag "android.x.y.z" referenced, add a 995*b9df5ad1SAndroid Build Coastguard Worker # "@see ACAMERA_X_Y_Z" 996*b9df5ad1SAndroid Build Coastguard Worker def ndkdoc_crossref_see_filter(node_set): 997*b9df5ad1SAndroid Build Coastguard Worker node_set = (x for x in node_set if x.applied_ndk_visible == 'true') 998*b9df5ad1SAndroid Build Coastguard Worker 999*b9df5ad1SAndroid Build Coastguard Worker text = '\n' 1000*b9df5ad1SAndroid Build Coastguard Worker for node in node_set: 1001*b9df5ad1SAndroid Build Coastguard Worker text = text + '\n@see %s' % (csym(ndk(node.name))) 1002*b9df5ad1SAndroid Build Coastguard Worker 1003*b9df5ad1SAndroid Build Coastguard Worker return text if text != '\n' else '' 1004*b9df5ad1SAndroid Build Coastguard Worker 1005*b9df5ad1SAndroid Build Coastguard Worker ndktext = filter_tags(ndktext, metadata, ndkdoc_crossref_filter, ndkdoc_crossref_see_filter) 1006*b9df5ad1SAndroid Build Coastguard Worker 1007*b9df5ad1SAndroid Build Coastguard Worker ndktext = ndk_replace_tag_wildcards(ndktext, metadata) 1008*b9df5ad1SAndroid Build Coastguard Worker 1009*b9df5ad1SAndroid Build Coastguard Worker comment_prefix = " " * indent + " * "; 1010*b9df5ad1SAndroid Build Coastguard Worker 1011*b9df5ad1SAndroid Build Coastguard Worker def line_filter(line): 1012*b9df5ad1SAndroid Build Coastguard Worker # Indent each line 1013*b9df5ad1SAndroid Build Coastguard Worker # Add ' * ' to it for stylistic reasons 1014*b9df5ad1SAndroid Build Coastguard Worker # Strip right side of trailing whitespace 1015*b9df5ad1SAndroid Build Coastguard Worker return (comment_prefix + line).rstrip() 1016*b9df5ad1SAndroid Build Coastguard Worker 1017*b9df5ad1SAndroid Build Coastguard Worker # Process each line with above filter 1018*b9df5ad1SAndroid Build Coastguard Worker ndktext = "\n".join(line_filter(i) for i in ndktext.split("\n")) + "\n" 1019*b9df5ad1SAndroid Build Coastguard Worker 1020*b9df5ad1SAndroid Build Coastguard Worker return ndktext 1021*b9df5ad1SAndroid Build Coastguard Worker 1022*b9df5ad1SAndroid Build Coastguard Worker return ndkdoc_formatter 1023*b9df5ad1SAndroid Build Coastguard Worker 1024*b9df5ad1SAndroid Build Coastguard Workerdef hidldoc(metadata, indent = 4): 1025*b9df5ad1SAndroid Build Coastguard Worker """ 1026*b9df5ad1SAndroid Build Coastguard Worker Returns a function to format a markdown syntax text block as a 1027*b9df5ad1SAndroid Build Coastguard Worker HIDL camera HAL module C/C++ comment section, given a set of metadata 1028*b9df5ad1SAndroid Build Coastguard Worker 1029*b9df5ad1SAndroid Build Coastguard Worker Args: 1030*b9df5ad1SAndroid Build Coastguard Worker metadata: A Metadata instance, representing the top-level root 1031*b9df5ad1SAndroid Build Coastguard Worker of the metadata for cross-referencing 1032*b9df5ad1SAndroid Build Coastguard Worker indent: baseline level of indentation for comment block 1033*b9df5ad1SAndroid Build Coastguard Worker Returns: 1034*b9df5ad1SAndroid Build Coastguard Worker A function that transforms a String text block as follows: 1035*b9df5ad1SAndroid Build Coastguard Worker - Indent and * for insertion into a comment block 1036*b9df5ad1SAndroid Build Coastguard Worker - Trailing whitespace removed 1037*b9df5ad1SAndroid Build Coastguard Worker - Entire body rendered via markdown 1038*b9df5ad1SAndroid Build Coastguard Worker - All tag names converted to appropriate HIDL tag name for each tag 1039*b9df5ad1SAndroid Build Coastguard Worker 1040*b9df5ad1SAndroid Build Coastguard Worker Example: 1041*b9df5ad1SAndroid Build Coastguard Worker "This is a comment for NDK\n" + 1042*b9df5ad1SAndroid Build Coastguard Worker " with multiple lines, that should be \n" + 1043*b9df5ad1SAndroid Build Coastguard Worker " formatted better\n" + 1044*b9df5ad1SAndroid Build Coastguard Worker "\n" + 1045*b9df5ad1SAndroid Build Coastguard Worker " That covers multiple lines as well\n" 1046*b9df5ad1SAndroid Build Coastguard Worker " And references android.control.mode\n" 1047*b9df5ad1SAndroid Build Coastguard Worker 1048*b9df5ad1SAndroid Build Coastguard Worker transforms to 1049*b9df5ad1SAndroid Build Coastguard Worker " * This is a comment for NDK\n" + 1050*b9df5ad1SAndroid Build Coastguard Worker " * with multiple lines, that should be\n" + 1051*b9df5ad1SAndroid Build Coastguard Worker " * formatted better\n" + 1052*b9df5ad1SAndroid Build Coastguard Worker " * That covers multiple lines as well\n" + 1053*b9df5ad1SAndroid Build Coastguard Worker " * and references ANDROID_CONTROL_MODE\n" + 1054*b9df5ad1SAndroid Build Coastguard Worker " *\n" + 1055*b9df5ad1SAndroid Build Coastguard Worker " * @see ANDROID_CONTROL_MODE\n" 1056*b9df5ad1SAndroid Build Coastguard Worker """ 1057*b9df5ad1SAndroid Build Coastguard Worker def hidldoc_formatter(text): 1058*b9df5ad1SAndroid Build Coastguard Worker # render with markdown => HTML 1059*b9df5ad1SAndroid Build Coastguard Worker # Turn off the table plugin since doxygen doesn't recognize generated <thead> <tbody> tags 1060*b9df5ad1SAndroid Build Coastguard Worker hidltext = md(text, NDKDOC_IMAGE_SRC_METADATA, False) 1061*b9df5ad1SAndroid Build Coastguard Worker 1062*b9df5ad1SAndroid Build Coastguard Worker # Simple transform for hidl doc links 1063*b9df5ad1SAndroid Build Coastguard Worker def hidldoc_link_filter(target, target_ndk, shortname): 1064*b9df5ad1SAndroid Build Coastguard Worker if target_ndk is not None: 1065*b9df5ad1SAndroid Build Coastguard Worker return '{@link %s %s}' % (target_ndk, shortname) 1066*b9df5ad1SAndroid Build Coastguard Worker 1067*b9df5ad1SAndroid Build Coastguard Worker # Create HTML link to Javadoc 1068*b9df5ad1SAndroid Build Coastguard Worker if shortname == '': 1069*b9df5ad1SAndroid Build Coastguard Worker lastdot = target.rfind('.') 1070*b9df5ad1SAndroid Build Coastguard Worker if lastdot == -1: 1071*b9df5ad1SAndroid Build Coastguard Worker shortname = target 1072*b9df5ad1SAndroid Build Coastguard Worker else: 1073*b9df5ad1SAndroid Build Coastguard Worker shortname = target[lastdot + 1:] 1074*b9df5ad1SAndroid Build Coastguard Worker 1075*b9df5ad1SAndroid Build Coastguard Worker target = target.replace('.','/') 1076*b9df5ad1SAndroid Build Coastguard Worker if target.find('#') != -1: 1077*b9df5ad1SAndroid Build Coastguard Worker target = target.replace('#','.html#') 1078*b9df5ad1SAndroid Build Coastguard Worker else: 1079*b9df5ad1SAndroid Build Coastguard Worker target = target + '.html' 1080*b9df5ad1SAndroid Build Coastguard Worker 1081*b9df5ad1SAndroid Build Coastguard Worker return '<a href="https://developer.android.com/reference/%s">%s</a>' % (target, shortname) 1082*b9df5ad1SAndroid Build Coastguard Worker 1083*b9df5ad1SAndroid Build Coastguard Worker hidltext = filter_links(hidltext, hidldoc_link_filter) 1084*b9df5ad1SAndroid Build Coastguard Worker 1085*b9df5ad1SAndroid Build Coastguard Worker # Convert metadata entry "android.x.y.z" to form 1086*b9df5ad1SAndroid Build Coastguard Worker # HIDL tag format of "ANDROID_X_Y_Z" 1087*b9df5ad1SAndroid Build Coastguard Worker def hidldoc_crossref_filter(node): 1088*b9df5ad1SAndroid Build Coastguard Worker return csym(node.name) 1089*b9df5ad1SAndroid Build Coastguard Worker 1090*b9df5ad1SAndroid Build Coastguard Worker # For each public tag "android.x.y.z" referenced, add a 1091*b9df5ad1SAndroid Build Coastguard Worker # "@see ANDROID_X_Y_Z" 1092*b9df5ad1SAndroid Build Coastguard Worker def hidldoc_crossref_see_filter(node_set): 1093*b9df5ad1SAndroid Build Coastguard Worker text = '\n' 1094*b9df5ad1SAndroid Build Coastguard Worker for node in node_set: 1095*b9df5ad1SAndroid Build Coastguard Worker text = text + '\n@see %s' % (csym(node.name)) 1096*b9df5ad1SAndroid Build Coastguard Worker 1097*b9df5ad1SAndroid Build Coastguard Worker return text if text != '\n' else '' 1098*b9df5ad1SAndroid Build Coastguard Worker 1099*b9df5ad1SAndroid Build Coastguard Worker hidltext = filter_tags(hidltext, metadata, hidldoc_crossref_filter, hidldoc_crossref_see_filter) 1100*b9df5ad1SAndroid Build Coastguard Worker 1101*b9df5ad1SAndroid Build Coastguard Worker comment_prefix = " " * indent + " * "; 1102*b9df5ad1SAndroid Build Coastguard Worker 1103*b9df5ad1SAndroid Build Coastguard Worker def line_filter(line): 1104*b9df5ad1SAndroid Build Coastguard Worker # Indent each line 1105*b9df5ad1SAndroid Build Coastguard Worker # Add ' * ' to it for stylistic reasons 1106*b9df5ad1SAndroid Build Coastguard Worker # Strip right side of trailing whitespace 1107*b9df5ad1SAndroid Build Coastguard Worker return (comment_prefix + line).rstrip() 1108*b9df5ad1SAndroid Build Coastguard Worker 1109*b9df5ad1SAndroid Build Coastguard Worker # Process each line with above filter 1110*b9df5ad1SAndroid Build Coastguard Worker hidltext = "\n".join(line_filter(i) for i in hidltext.split("\n")) + "\n" 1111*b9df5ad1SAndroid Build Coastguard Worker 1112*b9df5ad1SAndroid Build Coastguard Worker return hidltext 1113*b9df5ad1SAndroid Build Coastguard Worker 1114*b9df5ad1SAndroid Build Coastguard Worker return hidldoc_formatter 1115*b9df5ad1SAndroid Build Coastguard Worker 1116*b9df5ad1SAndroid Build Coastguard Workerdef dedent(text): 1117*b9df5ad1SAndroid Build Coastguard Worker """ 1118*b9df5ad1SAndroid Build Coastguard Worker Remove all common indentation from every line but the 0th. 1119*b9df5ad1SAndroid Build Coastguard Worker This will avoid getting <code> blocks when rendering text via markdown. 1120*b9df5ad1SAndroid Build Coastguard Worker Ignoring the 0th line will also allow the 0th line not to be aligned. 1121*b9df5ad1SAndroid Build Coastguard Worker 1122*b9df5ad1SAndroid Build Coastguard Worker Args: 1123*b9df5ad1SAndroid Build Coastguard Worker text: A string of text to dedent. 1124*b9df5ad1SAndroid Build Coastguard Worker 1125*b9df5ad1SAndroid Build Coastguard Worker Returns: 1126*b9df5ad1SAndroid Build Coastguard Worker String dedented by above rules. 1127*b9df5ad1SAndroid Build Coastguard Worker 1128*b9df5ad1SAndroid Build Coastguard Worker For example: 1129*b9df5ad1SAndroid Build Coastguard Worker assertEquals("bar\nline1\nline2", dedent("bar\n line1\n line2")) 1130*b9df5ad1SAndroid Build Coastguard Worker assertEquals("bar\nline1\nline2", dedent(" bar\n line1\n line2")) 1131*b9df5ad1SAndroid Build Coastguard Worker assertEquals("bar\n line1\nline2", dedent(" bar\n line1\n line2")) 1132*b9df5ad1SAndroid Build Coastguard Worker """ 1133*b9df5ad1SAndroid Build Coastguard Worker text = textwrap.dedent(text) 1134*b9df5ad1SAndroid Build Coastguard Worker text_lines = text.split('\n') 1135*b9df5ad1SAndroid Build Coastguard Worker text_not_first = "\n".join(text_lines[1:]) 1136*b9df5ad1SAndroid Build Coastguard Worker text_not_first = textwrap.dedent(text_not_first) 1137*b9df5ad1SAndroid Build Coastguard Worker text = text_lines[0] + "\n" + text_not_first 1138*b9df5ad1SAndroid Build Coastguard Worker 1139*b9df5ad1SAndroid Build Coastguard Worker return text 1140*b9df5ad1SAndroid Build Coastguard Worker 1141*b9df5ad1SAndroid Build Coastguard Workerdef md(text, img_src_prefix="", table_ext=True): 1142*b9df5ad1SAndroid Build Coastguard Worker """ 1143*b9df5ad1SAndroid Build Coastguard Worker Run text through markdown to produce HTML. 1144*b9df5ad1SAndroid Build Coastguard Worker 1145*b9df5ad1SAndroid Build Coastguard Worker This also removes all common indentation from every line but the 0th. 1146*b9df5ad1SAndroid Build Coastguard Worker This will avoid getting <code> blocks in markdown. 1147*b9df5ad1SAndroid Build Coastguard Worker Ignoring the 0th line will also allow the 0th line not to be aligned. 1148*b9df5ad1SAndroid Build Coastguard Worker 1149*b9df5ad1SAndroid Build Coastguard Worker Args: 1150*b9df5ad1SAndroid Build Coastguard Worker text: A markdown-syntax using block of text to format. 1151*b9df5ad1SAndroid Build Coastguard Worker img_src_prefix: An optional string to prepend to each <img src="target"/> 1152*b9df5ad1SAndroid Build Coastguard Worker 1153*b9df5ad1SAndroid Build Coastguard Worker Returns: 1154*b9df5ad1SAndroid Build Coastguard Worker String rendered by markdown and other rules applied (see above). 1155*b9df5ad1SAndroid Build Coastguard Worker 1156*b9df5ad1SAndroid Build Coastguard Worker For example, this avoids the following situation: 1157*b9df5ad1SAndroid Build Coastguard Worker 1158*b9df5ad1SAndroid Build Coastguard Worker <!-- Input --> 1159*b9df5ad1SAndroid Build Coastguard Worker 1160*b9df5ad1SAndroid Build Coastguard Worker <!--- can't use dedent directly since 'foo' has no indent --> 1161*b9df5ad1SAndroid Build Coastguard Worker <notes>foo 1162*b9df5ad1SAndroid Build Coastguard Worker bar 1163*b9df5ad1SAndroid Build Coastguard Worker bar 1164*b9df5ad1SAndroid Build Coastguard Worker </notes> 1165*b9df5ad1SAndroid Build Coastguard Worker 1166*b9df5ad1SAndroid Build Coastguard Worker <!-- Bad Output -- > 1167*b9df5ad1SAndroid Build Coastguard Worker <!-- if no dedent is done generated code looks like --> 1168*b9df5ad1SAndroid Build Coastguard Worker <p>foo 1169*b9df5ad1SAndroid Build Coastguard Worker <code><pre> 1170*b9df5ad1SAndroid Build Coastguard Worker bar 1171*b9df5ad1SAndroid Build Coastguard Worker bar</pre></code> 1172*b9df5ad1SAndroid Build Coastguard Worker </p> 1173*b9df5ad1SAndroid Build Coastguard Worker 1174*b9df5ad1SAndroid Build Coastguard Worker Instead we get the more natural expected result: 1175*b9df5ad1SAndroid Build Coastguard Worker 1176*b9df5ad1SAndroid Build Coastguard Worker <!-- Good Output --> 1177*b9df5ad1SAndroid Build Coastguard Worker <p>foo 1178*b9df5ad1SAndroid Build Coastguard Worker bar 1179*b9df5ad1SAndroid Build Coastguard Worker bar</p> 1180*b9df5ad1SAndroid Build Coastguard Worker 1181*b9df5ad1SAndroid Build Coastguard Worker """ 1182*b9df5ad1SAndroid Build Coastguard Worker text = dedent(text) 1183*b9df5ad1SAndroid Build Coastguard Worker 1184*b9df5ad1SAndroid Build Coastguard Worker # full list of extensions at http://pythonhosted.org/Markdown/extensions/ 1185*b9df5ad1SAndroid Build Coastguard Worker md_extensions = ['tables'] if table_ext else []# make <table> with ASCII |_| tables 1186*b9df5ad1SAndroid Build Coastguard Worker # render with markdown 1187*b9df5ad1SAndroid Build Coastguard Worker text = markdown.markdown(text, extensions=md_extensions) 1188*b9df5ad1SAndroid Build Coastguard Worker 1189*b9df5ad1SAndroid Build Coastguard Worker # prepend a prefix to each <img src="foo"> -> <img src="${prefix}foo"> 1190*b9df5ad1SAndroid Build Coastguard Worker text = re.sub(r'src="([^"]*)"', 'src="' + img_src_prefix + r'\1"', text) 1191*b9df5ad1SAndroid Build Coastguard Worker return text 1192*b9df5ad1SAndroid Build Coastguard Worker 1193*b9df5ad1SAndroid Build Coastguard Workerdef filter_tags(text, metadata, filter_function, summary_function = None): 1194*b9df5ad1SAndroid Build Coastguard Worker """ 1195*b9df5ad1SAndroid Build Coastguard Worker Find all references to tags in the form outer_namespace.xxx.yyy[.zzz] in 1196*b9df5ad1SAndroid Build Coastguard Worker the provided text, and pass them through filter_function and summary_function. 1197*b9df5ad1SAndroid Build Coastguard Worker 1198*b9df5ad1SAndroid Build Coastguard Worker Used to linkify entry names in HMTL, javadoc output. 1199*b9df5ad1SAndroid Build Coastguard Worker 1200*b9df5ad1SAndroid Build Coastguard Worker Args: 1201*b9df5ad1SAndroid Build Coastguard Worker text: A string representing a block of text destined for output 1202*b9df5ad1SAndroid Build Coastguard Worker metadata: A Metadata instance, the root of the metadata properties tree 1203*b9df5ad1SAndroid Build Coastguard Worker filter_function: A Node->string function to apply to each node 1204*b9df5ad1SAndroid Build Coastguard Worker when found in text; the string returned replaces the tag name in text. 1205*b9df5ad1SAndroid Build Coastguard Worker summary_function: A Node list->string function that is provided the list of 1206*b9df5ad1SAndroid Build Coastguard Worker unique tag nodes found in text, and which must return a string that is 1207*b9df5ad1SAndroid Build Coastguard Worker then appended to the end of the text. The list is sorted alphabetically 1208*b9df5ad1SAndroid Build Coastguard Worker by node name. 1209*b9df5ad1SAndroid Build Coastguard Worker """ 1210*b9df5ad1SAndroid Build Coastguard Worker 1211*b9df5ad1SAndroid Build Coastguard Worker tag_set = set() 1212*b9df5ad1SAndroid Build Coastguard Worker def name_match(name): 1213*b9df5ad1SAndroid Build Coastguard Worker return lambda node: node.name == name 1214*b9df5ad1SAndroid Build Coastguard Worker 1215*b9df5ad1SAndroid Build Coastguard Worker # Match outer_namespace.x.y or outer_namespace.x.y.z, making sure 1216*b9df5ad1SAndroid Build Coastguard Worker # to grab .z and not just outer_namespace.x.y. (sloppy, but since we 1217*b9df5ad1SAndroid Build Coastguard Worker # check for validity, a few false positives don't hurt). 1218*b9df5ad1SAndroid Build Coastguard Worker # Try to ignore items of the form {@link <outer_namespace>... 1219*b9df5ad1SAndroid Build Coastguard Worker for outer_namespace in metadata.outer_namespaces: 1220*b9df5ad1SAndroid Build Coastguard Worker 1221*b9df5ad1SAndroid Build Coastguard Worker tag_match = r"(?<!\{@link\s)" + outer_namespace.name + \ 1222*b9df5ad1SAndroid Build Coastguard Worker r"\.([a-zA-Z0-9\n]+)\.([a-zA-Z0-9\n]+)(\.[a-zA-Z0-9\n]+)?([/]?)" 1223*b9df5ad1SAndroid Build Coastguard Worker 1224*b9df5ad1SAndroid Build Coastguard Worker def filter_sub(match): 1225*b9df5ad1SAndroid Build Coastguard Worker whole_match = match.group(0) 1226*b9df5ad1SAndroid Build Coastguard Worker section1 = match.group(1) 1227*b9df5ad1SAndroid Build Coastguard Worker section2 = match.group(2) 1228*b9df5ad1SAndroid Build Coastguard Worker section3 = match.group(3) 1229*b9df5ad1SAndroid Build Coastguard Worker end_slash = match.group(4) 1230*b9df5ad1SAndroid Build Coastguard Worker 1231*b9df5ad1SAndroid Build Coastguard Worker # Don't linkify things ending in slash (urls, for example) 1232*b9df5ad1SAndroid Build Coastguard Worker if end_slash: 1233*b9df5ad1SAndroid Build Coastguard Worker return whole_match 1234*b9df5ad1SAndroid Build Coastguard Worker 1235*b9df5ad1SAndroid Build Coastguard Worker candidate = "" 1236*b9df5ad1SAndroid Build Coastguard Worker 1237*b9df5ad1SAndroid Build Coastguard Worker # First try a two-level match 1238*b9df5ad1SAndroid Build Coastguard Worker candidate2 = "%s.%s.%s" % (outer_namespace.name, section1, section2) 1239*b9df5ad1SAndroid Build Coastguard Worker got_two_level = False 1240*b9df5ad1SAndroid Build Coastguard Worker 1241*b9df5ad1SAndroid Build Coastguard Worker node = metadata.find_first(name_match(candidate2.replace('\n',''))) 1242*b9df5ad1SAndroid Build Coastguard Worker if not node and '\n' in section2: 1243*b9df5ad1SAndroid Build Coastguard Worker # Linefeeds are ambiguous - was the intent to add a space, 1244*b9df5ad1SAndroid Build Coastguard Worker # or continue a lengthy name? Try the former now. 1245*b9df5ad1SAndroid Build Coastguard Worker candidate2b = "%s.%s.%s" % (outer_namespace.name, section1, section2[:section2.find('\n')]) 1246*b9df5ad1SAndroid Build Coastguard Worker node = metadata.find_first(name_match(candidate2b)) 1247*b9df5ad1SAndroid Build Coastguard Worker if node: 1248*b9df5ad1SAndroid Build Coastguard Worker candidate2 = candidate2b 1249*b9df5ad1SAndroid Build Coastguard Worker 1250*b9df5ad1SAndroid Build Coastguard Worker if node: 1251*b9df5ad1SAndroid Build Coastguard Worker # Have two-level match 1252*b9df5ad1SAndroid Build Coastguard Worker got_two_level = True 1253*b9df5ad1SAndroid Build Coastguard Worker candidate = candidate2 1254*b9df5ad1SAndroid Build Coastguard Worker elif section3: 1255*b9df5ad1SAndroid Build Coastguard Worker # Try three-level match 1256*b9df5ad1SAndroid Build Coastguard Worker candidate3 = "%s%s" % (candidate2, section3) 1257*b9df5ad1SAndroid Build Coastguard Worker node = metadata.find_first(name_match(candidate3.replace('\n',''))) 1258*b9df5ad1SAndroid Build Coastguard Worker 1259*b9df5ad1SAndroid Build Coastguard Worker if not node and '\n' in section3: 1260*b9df5ad1SAndroid Build Coastguard Worker # Linefeeds are ambiguous - was the intent to add a space, 1261*b9df5ad1SAndroid Build Coastguard Worker # or continue a lengthy name? Try the former now. 1262*b9df5ad1SAndroid Build Coastguard Worker candidate3b = "%s%s" % (candidate2, section3[:section3.find('\n')]) 1263*b9df5ad1SAndroid Build Coastguard Worker node = metadata.find_first(name_match(candidate3b)) 1264*b9df5ad1SAndroid Build Coastguard Worker if node: 1265*b9df5ad1SAndroid Build Coastguard Worker candidate3 = candidate3b 1266*b9df5ad1SAndroid Build Coastguard Worker 1267*b9df5ad1SAndroid Build Coastguard Worker if node: 1268*b9df5ad1SAndroid Build Coastguard Worker # Have 3-level match 1269*b9df5ad1SAndroid Build Coastguard Worker candidate = candidate3 1270*b9df5ad1SAndroid Build Coastguard Worker 1271*b9df5ad1SAndroid Build Coastguard Worker # Replace match with crossref or complain if a likely match couldn't be matched 1272*b9df5ad1SAndroid Build Coastguard Worker 1273*b9df5ad1SAndroid Build Coastguard Worker if node: 1274*b9df5ad1SAndroid Build Coastguard Worker tag_set.add(node) 1275*b9df5ad1SAndroid Build Coastguard Worker return whole_match.replace(candidate,filter_function(node)) 1276*b9df5ad1SAndroid Build Coastguard Worker else: 1277*b9df5ad1SAndroid Build Coastguard Worker print(" WARNING: Could not crossref likely reference {%s}" % (match.group(0)), 1278*b9df5ad1SAndroid Build Coastguard Worker file=sys.stderr) 1279*b9df5ad1SAndroid Build Coastguard Worker return whole_match 1280*b9df5ad1SAndroid Build Coastguard Worker 1281*b9df5ad1SAndroid Build Coastguard Worker text = re.sub(tag_match, filter_sub, text) 1282*b9df5ad1SAndroid Build Coastguard Worker 1283*b9df5ad1SAndroid Build Coastguard Worker if summary_function is not None: 1284*b9df5ad1SAndroid Build Coastguard Worker return text + summary_function(sorted(tag_set, key=lambda x: x.name)) 1285*b9df5ad1SAndroid Build Coastguard Worker else: 1286*b9df5ad1SAndroid Build Coastguard Worker return text 1287*b9df5ad1SAndroid Build Coastguard Worker 1288*b9df5ad1SAndroid Build Coastguard Workerdef ndk_replace_tag_wildcards(text, metadata): 1289*b9df5ad1SAndroid Build Coastguard Worker """ 1290*b9df5ad1SAndroid Build Coastguard Worker Find all references to tags in the form android.xxx.* or android.xxx.yyy.* 1291*b9df5ad1SAndroid Build Coastguard Worker in the provided text, and replace them by NDK format of "ACAMERA_XXX_*" or 1292*b9df5ad1SAndroid Build Coastguard Worker "ACAMERA_XXX_YYY_*" 1293*b9df5ad1SAndroid Build Coastguard Worker 1294*b9df5ad1SAndroid Build Coastguard Worker Args: 1295*b9df5ad1SAndroid Build Coastguard Worker text: A string representing a block of text destined for output 1296*b9df5ad1SAndroid Build Coastguard Worker metadata: A Metadata instance, the root of the metadata properties tree 1297*b9df5ad1SAndroid Build Coastguard Worker """ 1298*b9df5ad1SAndroid Build Coastguard Worker tag_match = r"android\.([a-zA-Z0-9\n]+)\.\*" 1299*b9df5ad1SAndroid Build Coastguard Worker tag_match_2 = r"android\.([a-zA-Z0-9\n]+)\.([a-zA-Z0-9\n]+)\*" 1300*b9df5ad1SAndroid Build Coastguard Worker 1301*b9df5ad1SAndroid Build Coastguard Worker def filter_sub(match): 1302*b9df5ad1SAndroid Build Coastguard Worker return "ACAMERA_" + match.group(1).upper() + "_*" 1303*b9df5ad1SAndroid Build Coastguard Worker def filter_sub_2(match): 1304*b9df5ad1SAndroid Build Coastguard Worker return "ACAMERA_" + match.group(1).upper() + match.group(2).upper() + "_*" 1305*b9df5ad1SAndroid Build Coastguard Worker 1306*b9df5ad1SAndroid Build Coastguard Worker text = re.sub(tag_match, filter_sub, text) 1307*b9df5ad1SAndroid Build Coastguard Worker text = re.sub(tag_match_2, filter_sub_2, text) 1308*b9df5ad1SAndroid Build Coastguard Worker return text 1309*b9df5ad1SAndroid Build Coastguard Worker 1310*b9df5ad1SAndroid Build Coastguard Workerdef filter_links(text, filter_function, summary_function = None): 1311*b9df5ad1SAndroid Build Coastguard Worker """ 1312*b9df5ad1SAndroid Build Coastguard Worker Find all references to tags in the form {@link xxx#yyy [zzz]} in the 1313*b9df5ad1SAndroid Build Coastguard Worker provided text, and pass them through filter_function and 1314*b9df5ad1SAndroid Build Coastguard Worker summary_function. 1315*b9df5ad1SAndroid Build Coastguard Worker 1316*b9df5ad1SAndroid Build Coastguard Worker Used to linkify documentation cross-references in HMTL, javadoc output. 1317*b9df5ad1SAndroid Build Coastguard Worker 1318*b9df5ad1SAndroid Build Coastguard Worker Args: 1319*b9df5ad1SAndroid Build Coastguard Worker text: A string representing a block of text destined for output 1320*b9df5ad1SAndroid Build Coastguard Worker metadata: A Metadata instance, the root of the metadata properties tree 1321*b9df5ad1SAndroid Build Coastguard Worker filter_function: A (string, string)->string function to apply to each 'xxx#yyy', 1322*b9df5ad1SAndroid Build Coastguard Worker zzz pair when found in text; the string returned replaces the tag name in text. 1323*b9df5ad1SAndroid Build Coastguard Worker summary_function: A string list->string function that is provided the list of 1324*b9df5ad1SAndroid Build Coastguard Worker unique targets found in text, and which must return a string that is 1325*b9df5ad1SAndroid Build Coastguard Worker then appended to the end of the text. The list is sorted alphabetically 1326*b9df5ad1SAndroid Build Coastguard Worker by node name. 1327*b9df5ad1SAndroid Build Coastguard Worker 1328*b9df5ad1SAndroid Build Coastguard Worker """ 1329*b9df5ad1SAndroid Build Coastguard Worker 1330*b9df5ad1SAndroid Build Coastguard Worker target_set = set() 1331*b9df5ad1SAndroid Build Coastguard Worker def name_match(name): 1332*b9df5ad1SAndroid Build Coastguard Worker return lambda node: node.name == name 1333*b9df5ad1SAndroid Build Coastguard Worker 1334*b9df5ad1SAndroid Build Coastguard Worker tag_match = r"\{@link\s+([^\s\}\|]+)(?:\|([^\s\}]+))*([^\}]*)\}" 1335*b9df5ad1SAndroid Build Coastguard Worker 1336*b9df5ad1SAndroid Build Coastguard Worker def filter_sub(match): 1337*b9df5ad1SAndroid Build Coastguard Worker whole_match = match.group(0) 1338*b9df5ad1SAndroid Build Coastguard Worker target = match.group(1) 1339*b9df5ad1SAndroid Build Coastguard Worker target_ndk = match.group(2) 1340*b9df5ad1SAndroid Build Coastguard Worker shortname = match.group(3).strip() 1341*b9df5ad1SAndroid Build Coastguard Worker 1342*b9df5ad1SAndroid Build Coastguard Worker #print("Found link '%s' ndk '%s' as '%s' -> '%s'" % (target, target_ndk, shortname, filter_function(target, target_ndk, shortname))) 1343*b9df5ad1SAndroid Build Coastguard Worker 1344*b9df5ad1SAndroid Build Coastguard Worker # Replace match with crossref 1345*b9df5ad1SAndroid Build Coastguard Worker target_set.add(target) 1346*b9df5ad1SAndroid Build Coastguard Worker return filter_function(target, target_ndk, shortname) 1347*b9df5ad1SAndroid Build Coastguard Worker 1348*b9df5ad1SAndroid Build Coastguard Worker text = re.sub(tag_match, filter_sub, text) 1349*b9df5ad1SAndroid Build Coastguard Worker 1350*b9df5ad1SAndroid Build Coastguard Worker if summary_function is not None: 1351*b9df5ad1SAndroid Build Coastguard Worker return text + summary_function(sorted(target_set)) 1352*b9df5ad1SAndroid Build Coastguard Worker else: 1353*b9df5ad1SAndroid Build Coastguard Worker return text 1354*b9df5ad1SAndroid Build Coastguard Worker 1355*b9df5ad1SAndroid Build Coastguard Workerdef any_visible(section, kind_name, visibilities): 1356*b9df5ad1SAndroid Build Coastguard Worker """ 1357*b9df5ad1SAndroid Build Coastguard Worker Determine if entries in this section have an applied visibility that's in 1358*b9df5ad1SAndroid Build Coastguard Worker the list of given visibilities. 1359*b9df5ad1SAndroid Build Coastguard Worker 1360*b9df5ad1SAndroid Build Coastguard Worker Args: 1361*b9df5ad1SAndroid Build Coastguard Worker section: A section of metadata 1362*b9df5ad1SAndroid Build Coastguard Worker kind_name: A name of the kind, i.e. 'dynamic' or 'static' or 'controls' 1363*b9df5ad1SAndroid Build Coastguard Worker visibilities: An iterable of visibilities to match against 1364*b9df5ad1SAndroid Build Coastguard Worker 1365*b9df5ad1SAndroid Build Coastguard Worker Returns: 1366*b9df5ad1SAndroid Build Coastguard Worker True if the section has any entries with any of the given visibilities. False otherwise. 1367*b9df5ad1SAndroid Build Coastguard Worker """ 1368*b9df5ad1SAndroid Build Coastguard Worker 1369*b9df5ad1SAndroid Build Coastguard Worker for inner_namespace in get_children_by_filtering_kind(section, kind_name, 1370*b9df5ad1SAndroid Build Coastguard Worker 'namespaces'): 1371*b9df5ad1SAndroid Build Coastguard Worker if any(filter_visibility(inner_namespace.merged_entries, visibilities)): 1372*b9df5ad1SAndroid Build Coastguard Worker return True 1373*b9df5ad1SAndroid Build Coastguard Worker 1374*b9df5ad1SAndroid Build Coastguard Worker return any(filter_visibility(get_children_by_filtering_kind(section, kind_name, 1375*b9df5ad1SAndroid Build Coastguard Worker 'merged_entries'), 1376*b9df5ad1SAndroid Build Coastguard Worker visibilities)) 1377*b9df5ad1SAndroid Build Coastguard Worker 1378*b9df5ad1SAndroid Build Coastguard Workerdef filter_visibility(entries, visibilities): 1379*b9df5ad1SAndroid Build Coastguard Worker """ 1380*b9df5ad1SAndroid Build Coastguard Worker Remove entries whose applied visibility is not in the supplied visibilities. 1381*b9df5ad1SAndroid Build Coastguard Worker 1382*b9df5ad1SAndroid Build Coastguard Worker Args: 1383*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1384*b9df5ad1SAndroid Build Coastguard Worker visibilities: An iterable of visibilities to filter against 1385*b9df5ad1SAndroid Build Coastguard Worker 1386*b9df5ad1SAndroid Build Coastguard Worker Yields: 1387*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1388*b9df5ad1SAndroid Build Coastguard Worker """ 1389*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if e.applied_visibility in visibilities) 1390*b9df5ad1SAndroid Build Coastguard Worker 1391*b9df5ad1SAndroid Build Coastguard Workerdef is_not_hal_visible(e): 1392*b9df5ad1SAndroid Build Coastguard Worker """ 1393*b9df5ad1SAndroid Build Coastguard Worker Determine that the entry being passed in is not visible to HAL. 1394*b9df5ad1SAndroid Build Coastguard Worker 1395*b9df5ad1SAndroid Build Coastguard Worker Args: 1396*b9df5ad1SAndroid Build Coastguard Worker e: An entry node 1397*b9df5ad1SAndroid Build Coastguard Worker 1398*b9df5ad1SAndroid Build Coastguard Worker Returns: 1399*b9df5ad1SAndroid Build Coastguard Worker True if the entry is not visible to HAL 1400*b9df5ad1SAndroid Build Coastguard Worker """ 1401*b9df5ad1SAndroid Build Coastguard Worker return (e.visibility == 'fwk_only' or 1402*b9df5ad1SAndroid Build Coastguard Worker e.visibility == 'fwk_java_public' or 1403*b9df5ad1SAndroid Build Coastguard Worker e.visibility == 'fwk_public' or 1404*b9df5ad1SAndroid Build Coastguard Worker e.visibility == 'fwk_system_public' or 1405*b9df5ad1SAndroid Build Coastguard Worker e.visibility == 'fwk_ndk_public' or 1406*b9df5ad1SAndroid Build Coastguard Worker e.visibility == 'extension') 1407*b9df5ad1SAndroid Build Coastguard Worker 1408*b9df5ad1SAndroid Build Coastguard Workerdef remove_hal_non_visible(entries): 1409*b9df5ad1SAndroid Build Coastguard Worker """ 1410*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries by removing those that are not HAL visible: 1411*b9df5ad1SAndroid Build Coastguard Worker synthetic, fwk_only, extension, fwk_java_public, fwk_system_public, fwk_ndk_public, 1412*b9df5ad1SAndroid Build Coastguard Worker or fwk_public. 1413*b9df5ad1SAndroid Build Coastguard Worker 1414*b9df5ad1SAndroid Build Coastguard Worker Args: 1415*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1416*b9df5ad1SAndroid Build Coastguard Worker 1417*b9df5ad1SAndroid Build Coastguard Worker Yields: 1418*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1419*b9df5ad1SAndroid Build Coastguard Worker """ 1420*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if not (e.synthetic or is_not_hal_visible(e))) 1421*b9df5ad1SAndroid Build Coastguard Worker 1422*b9df5ad1SAndroid Build Coastguard Workerdef remove_ndk_non_visible(entries): 1423*b9df5ad1SAndroid Build Coastguard Worker """ 1424*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries by removing those that are not NDK visible: 1425*b9df5ad1SAndroid Build Coastguard Worker synthetic, fwk_only, extension, or fwk_java_public. 1426*b9df5ad1SAndroid Build Coastguard Worker 1427*b9df5ad1SAndroid Build Coastguard Worker Args: 1428*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1429*b9df5ad1SAndroid Build Coastguard Worker 1430*b9df5ad1SAndroid Build Coastguard Worker Yields: 1431*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1432*b9df5ad1SAndroid Build Coastguard Worker """ 1433*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if not (e.synthetic or e.visibility == 'fwk_only' 1434*b9df5ad1SAndroid Build Coastguard Worker or e.visibility == 'fwk_java_public' or 1435*b9df5ad1SAndroid Build Coastguard Worker e.visibility == 'extension')) 1436*b9df5ad1SAndroid Build Coastguard Worker 1437*b9df5ad1SAndroid Build Coastguard Worker""" 1438*b9df5ad1SAndroid Build Coastguard Worker Return the vndk version for a given hal minor version. The major version is assumed to be 3 1439*b9df5ad1SAndroid Build Coastguard Worker 1440*b9df5ad1SAndroid Build Coastguard Worker Args: 1441*b9df5ad1SAndroid Build Coastguard Worker hal_minor_version : minor version to retrieve the vndk version for 1442*b9df5ad1SAndroid Build Coastguard Worker 1443*b9df5ad1SAndroid Build Coastguard Worker Yields: 1444*b9df5ad1SAndroid Build Coastguard Worker int representing the vndk version 1445*b9df5ad1SAndroid Build Coastguard Worker """ 1446*b9df5ad1SAndroid Build Coastguard Workerdef get_vndk_version(hal_minor_version): 1447*b9df5ad1SAndroid Build Coastguard Worker if hal_minor_version <= FRAMEWORK_CAMERA_VNDK_HAL_MINOR_VERSION: 1448*b9df5ad1SAndroid Build Coastguard Worker return 0 1449*b9df5ad1SAndroid Build Coastguard Worker return hal_minor_version - FRAMEWORK_CAMERA_VNDK_HAL_MINOR_VERSION \ 1450*b9df5ad1SAndroid Build Coastguard Worker + FRAMEWORK_CAMERA_VNDK_STARTING_VERSION 1451*b9df5ad1SAndroid Build Coastguard Worker 1452*b9df5ad1SAndroid Build Coastguard Worker""" 1453*b9df5ad1SAndroid Build Coastguard Worker Returns an api level -> dict of metadata tags corresponding to the api level 1454*b9df5ad1SAndroid Build Coastguard Worker 1455*b9df5ad1SAndroid Build Coastguard Worker Args: 1456*b9df5ad1SAndroid Build Coastguard Worker sections : metadata sections to create the mapping for 1457*b9df5ad1SAndroid Build Coastguard Worker metadata: the metadata structure to be used to create the mapping 1458*b9df5ad1SAndroid Build Coastguard Worker kind : kind of entries to create a mapping for : 'static' or 'dynamic' 1459*b9df5ad1SAndroid Build Coastguard Worker 1460*b9df5ad1SAndroid Build Coastguard Worker Yields: 1461*b9df5ad1SAndroid Build Coastguard Worker A dictionary mapping api level to a dictionary of metadata tags for the particular key (api level) 1462*b9df5ad1SAndroid Build Coastguard Worker """ 1463*b9df5ad1SAndroid Build Coastguard Workerdef get_api_level_to_keys(sections, metadata, kind): 1464*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys = {} 1465*b9df5ad1SAndroid Build Coastguard Worker for sec in sections: 1466*b9df5ad1SAndroid Build Coastguard Worker for idx,entry in enumerate(remove_synthetic(find_unique_entries(sec))): 1467*b9df5ad1SAndroid Build Coastguard Worker if entry._hal_minor_version > FRAMEWORK_CAMERA_VNDK_HAL_MINOR_VERSION and \ 1468*b9df5ad1SAndroid Build Coastguard Worker metadata.is_entry_this_kind(entry, kind): 1469*b9df5ad1SAndroid Build Coastguard Worker api_level = get_vndk_version(entry._hal_minor_version) 1470*b9df5ad1SAndroid Build Coastguard Worker try: 1471*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys[api_level].add(entry.name) 1472*b9df5ad1SAndroid Build Coastguard Worker except KeyError: 1473*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys[api_level] = {entry.name} 1474*b9df5ad1SAndroid Build Coastguard Worker #Insert the keys in sorted order since dicts in python (< 3.7, even OrderedDicts don't actually 1475*b9df5ad1SAndroid Build Coastguard Worker # sort keys) 1476*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys_ordered = OrderedDict() 1477*b9df5ad1SAndroid Build Coastguard Worker for api_level_ordered in sorted(api_level_to_keys.keys()): 1478*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys_ordered[api_level_ordered] = sorted(api_level_to_keys[api_level_ordered]) 1479*b9df5ad1SAndroid Build Coastguard Worker return api_level_to_keys_ordered 1480*b9df5ad1SAndroid Build Coastguard Worker 1481*b9df5ad1SAndroid Build Coastguard Worker 1482*b9df5ad1SAndroid Build Coastguard Workerdef get_api_level_to_session_characteristic_keys(sections): 1483*b9df5ad1SAndroid Build Coastguard Worker """ 1484*b9df5ad1SAndroid Build Coastguard Worker Returns a mapping of api_level -> list session characteristics tag keys where api_level 1485*b9df5ad1SAndroid Build Coastguard Worker is the level at which they became a part of getSessionCharacteristics call. 1486*b9df5ad1SAndroid Build Coastguard Worker 1487*b9df5ad1SAndroid Build Coastguard Worker Args: 1488*b9df5ad1SAndroid Build Coastguard Worker sections : metadata sections to create the mapping for 1489*b9df5ad1SAndroid Build Coastguard Worker 1490*b9df5ad1SAndroid Build Coastguard Worker Returns: 1491*b9df5ad1SAndroid Build Coastguard Worker A dictionary mapping api level to a list of metadata tags. 1492*b9df5ad1SAndroid Build Coastguard Worker """ 1493*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys = defaultdict(list) 1494*b9df5ad1SAndroid Build Coastguard Worker for sec in sections: 1495*b9df5ad1SAndroid Build Coastguard Worker for entry in remove_synthetic(find_unique_entries(sec)): 1496*b9df5ad1SAndroid Build Coastguard Worker if entry.session_characteristics_key_since is None: 1497*b9df5ad1SAndroid Build Coastguard Worker continue 1498*b9df5ad1SAndroid Build Coastguard Worker 1499*b9df5ad1SAndroid Build Coastguard Worker api_level = entry.session_characteristics_key_since 1500*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys[api_level].append(entry.name) 1501*b9df5ad1SAndroid Build Coastguard Worker 1502*b9df5ad1SAndroid Build Coastguard Worker # sort dictionary on its key (api_level) 1503*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys = OrderedDict(sorted(api_level_to_keys.items(), key=itemgetter(0))) 1504*b9df5ad1SAndroid Build Coastguard Worker # sort the keys for each api_level 1505*b9df5ad1SAndroid Build Coastguard Worker for api_level, keys in api_level_to_keys.items(): 1506*b9df5ad1SAndroid Build Coastguard Worker api_level_to_keys[api_level] = sorted(keys) 1507*b9df5ad1SAndroid Build Coastguard Worker 1508*b9df5ad1SAndroid Build Coastguard Worker return api_level_to_keys 1509*b9df5ad1SAndroid Build Coastguard Worker 1510*b9df5ad1SAndroid Build Coastguard Worker 1511*b9df5ad1SAndroid Build Coastguard Workerdef remove_synthetic(entries): 1512*b9df5ad1SAndroid Build Coastguard Worker """ 1513*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries by removing those that are synthetic. 1514*b9df5ad1SAndroid Build Coastguard Worker 1515*b9df5ad1SAndroid Build Coastguard Worker Args: 1516*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1517*b9df5ad1SAndroid Build Coastguard Worker 1518*b9df5ad1SAndroid Build Coastguard Worker Yields: 1519*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1520*b9df5ad1SAndroid Build Coastguard Worker """ 1521*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if not e.synthetic) 1522*b9df5ad1SAndroid Build Coastguard Worker 1523*b9df5ad1SAndroid Build Coastguard Workerdef filter_added_in_hal_version(entries, hal_major_version, hal_minor_version): 1524*b9df5ad1SAndroid Build Coastguard Worker """ 1525*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries to those added in the given HIDL HAL version 1526*b9df5ad1SAndroid Build Coastguard Worker 1527*b9df5ad1SAndroid Build Coastguard Worker Args: 1528*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1529*b9df5ad1SAndroid Build Coastguard Worker hal_major_version: Major HIDL version to filter for 1530*b9df5ad1SAndroid Build Coastguard Worker hal_minor_version: Minor HIDL version to filter for 1531*b9df5ad1SAndroid Build Coastguard Worker 1532*b9df5ad1SAndroid Build Coastguard Worker Yields: 1533*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1534*b9df5ad1SAndroid Build Coastguard Worker """ 1535*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if e.hal_major_version == hal_major_version and e.hal_minor_version == hal_minor_version) 1536*b9df5ad1SAndroid Build Coastguard Worker 1537*b9df5ad1SAndroid Build Coastguard Workerdef filter_has_enum_values_added_in_hal_version(entries, hal_major_version, hal_minor_version): 1538*b9df5ad1SAndroid Build Coastguard Worker """ 1539*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries to those that have a new enum value added in the given HIDL HAL version 1540*b9df5ad1SAndroid Build Coastguard Worker 1541*b9df5ad1SAndroid Build Coastguard Worker Args: 1542*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1543*b9df5ad1SAndroid Build Coastguard Worker hal_major_version: Major HIDL version to filter for 1544*b9df5ad1SAndroid Build Coastguard Worker hal_minor_version: Minor HIDL version to filter for 1545*b9df5ad1SAndroid Build Coastguard Worker 1546*b9df5ad1SAndroid Build Coastguard Worker Yields: 1547*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1548*b9df5ad1SAndroid Build Coastguard Worker """ 1549*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if e.has_new_values_added_in_hal_version(hal_major_version, hal_minor_version)) 1550*b9df5ad1SAndroid Build Coastguard Worker 1551*b9df5ad1SAndroid Build Coastguard Workerdef permission_needed_count(root): 1552*b9df5ad1SAndroid Build Coastguard Worker """ 1553*b9df5ad1SAndroid Build Coastguard Worker Return the number entries that need camera permission. 1554*b9df5ad1SAndroid Build Coastguard Worker 1555*b9df5ad1SAndroid Build Coastguard Worker Args: 1556*b9df5ad1SAndroid Build Coastguard Worker root: a Metadata instance 1557*b9df5ad1SAndroid Build Coastguard Worker 1558*b9df5ad1SAndroid Build Coastguard Worker Returns: 1559*b9df5ad1SAndroid Build Coastguard Worker The number of entires that need camera permission. 1560*b9df5ad1SAndroid Build Coastguard Worker 1561*b9df5ad1SAndroid Build Coastguard Worker """ 1562*b9df5ad1SAndroid Build Coastguard Worker ret = 0 1563*b9df5ad1SAndroid Build Coastguard Worker for sec in find_all_sections(root): 1564*b9df5ad1SAndroid Build Coastguard Worker ret += len(list(filter_has_permission_needed(remove_hal_non_visible(find_unique_entries(sec))))) 1565*b9df5ad1SAndroid Build Coastguard Worker 1566*b9df5ad1SAndroid Build Coastguard Worker return ret 1567*b9df5ad1SAndroid Build Coastguard Worker 1568*b9df5ad1SAndroid Build Coastguard Workerdef filter_has_permission_needed(entries): 1569*b9df5ad1SAndroid Build Coastguard Worker """ 1570*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries by removing those that don't need camera permission. 1571*b9df5ad1SAndroid Build Coastguard Worker 1572*b9df5ad1SAndroid Build Coastguard Worker Args: 1573*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1574*b9df5ad1SAndroid Build Coastguard Worker 1575*b9df5ad1SAndroid Build Coastguard Worker Yields: 1576*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1577*b9df5ad1SAndroid Build Coastguard Worker """ 1578*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if e.permission_needed == 'true') 1579*b9df5ad1SAndroid Build Coastguard Worker 1580*b9df5ad1SAndroid Build Coastguard Workerdef filter_ndk_visible(entries): 1581*b9df5ad1SAndroid Build Coastguard Worker """ 1582*b9df5ad1SAndroid Build Coastguard Worker Filter the given entries by removing those that are not NDK visible. 1583*b9df5ad1SAndroid Build Coastguard Worker 1584*b9df5ad1SAndroid Build Coastguard Worker Args: 1585*b9df5ad1SAndroid Build Coastguard Worker entries: An iterable of Entry nodes 1586*b9df5ad1SAndroid Build Coastguard Worker 1587*b9df5ad1SAndroid Build Coastguard Worker Yields: 1588*b9df5ad1SAndroid Build Coastguard Worker An iterable of Entry nodes 1589*b9df5ad1SAndroid Build Coastguard Worker """ 1590*b9df5ad1SAndroid Build Coastguard Worker return (e for e in entries if e.applied_ndk_visible == 'true') 1591*b9df5ad1SAndroid Build Coastguard Worker 1592*b9df5ad1SAndroid Build Coastguard Workerdef wbr(text): 1593*b9df5ad1SAndroid Build Coastguard Worker """ 1594*b9df5ad1SAndroid Build Coastguard Worker Insert word break hints for the browser in the form of <wbr> HTML tags. 1595*b9df5ad1SAndroid Build Coastguard Worker 1596*b9df5ad1SAndroid Build Coastguard Worker Word breaks are inserted inside an HTML node only, so the nodes themselves 1597*b9df5ad1SAndroid Build Coastguard Worker will not be changed. Attributes are also left unchanged. 1598*b9df5ad1SAndroid Build Coastguard Worker 1599*b9df5ad1SAndroid Build Coastguard Worker The following rules apply to insert word breaks: 1600*b9df5ad1SAndroid Build Coastguard Worker - For characters in [ '.', '/', '_' ] 1601*b9df5ad1SAndroid Build Coastguard Worker - For uppercase letters inside a multi-word X.Y.Z (at least 3 parts) 1602*b9df5ad1SAndroid Build Coastguard Worker 1603*b9df5ad1SAndroid Build Coastguard Worker Args: 1604*b9df5ad1SAndroid Build Coastguard Worker text: A string of text containing HTML content. 1605*b9df5ad1SAndroid Build Coastguard Worker 1606*b9df5ad1SAndroid Build Coastguard Worker Returns: 1607*b9df5ad1SAndroid Build Coastguard Worker A string with <wbr> inserted by the above rules. 1608*b9df5ad1SAndroid Build Coastguard Worker """ 1609*b9df5ad1SAndroid Build Coastguard Worker SPLIT_CHARS_LIST = ['.', '_', '/'] 1610*b9df5ad1SAndroid Build Coastguard Worker SPLIT_CHARS = r'([.|/|_/,]+)' # split by these characters 1611*b9df5ad1SAndroid Build Coastguard Worker CAP_LETTER_MIN = 3 # at least 3 components split by above chars, i.e. x.y.z 1612*b9df5ad1SAndroid Build Coastguard Worker def wbr_filter(text): 1613*b9df5ad1SAndroid Build Coastguard Worker new_txt = text 1614*b9df5ad1SAndroid Build Coastguard Worker 1615*b9df5ad1SAndroid Build Coastguard Worker # for johnyOrange.appleCider.redGuardian also insert wbr before the caps 1616*b9df5ad1SAndroid Build Coastguard Worker # => johny<wbr>Orange.apple<wbr>Cider.red<wbr>Guardian 1617*b9df5ad1SAndroid Build Coastguard Worker for words in text.split(" "): 1618*b9df5ad1SAndroid Build Coastguard Worker for char in SPLIT_CHARS_LIST: 1619*b9df5ad1SAndroid Build Coastguard Worker # match at least x.y.z, don't match x or x.y 1620*b9df5ad1SAndroid Build Coastguard Worker if len(words.split(char)) >= CAP_LETTER_MIN: 1621*b9df5ad1SAndroid Build Coastguard Worker new_word = re.sub(r"([a-z])([A-Z])", r"\1<wbr>\2", words) 1622*b9df5ad1SAndroid Build Coastguard Worker new_txt = new_txt.replace(words, new_word) 1623*b9df5ad1SAndroid Build Coastguard Worker 1624*b9df5ad1SAndroid Build Coastguard Worker # e.g. X/Y/Z -> X/<wbr>Y/<wbr>/Z. also for X.Y.Z, X_Y_Z. 1625*b9df5ad1SAndroid Build Coastguard Worker new_txt = re.sub(SPLIT_CHARS, r"\1<wbr>", new_txt) 1626*b9df5ad1SAndroid Build Coastguard Worker 1627*b9df5ad1SAndroid Build Coastguard Worker return new_txt 1628*b9df5ad1SAndroid Build Coastguard Worker 1629*b9df5ad1SAndroid Build Coastguard Worker # Do not mangle HTML when doing the replace by using BeatifulSoup 1630*b9df5ad1SAndroid Build Coastguard Worker # - Use the 'html.parser' to avoid inserting <html><body> when decoding 1631*b9df5ad1SAndroid Build Coastguard Worker soup = bs4.BeautifulSoup(text, features='html.parser') 1632*b9df5ad1SAndroid Build Coastguard Worker wbr_tag = lambda: soup.new_tag('wbr') # must generate new tag every time 1633*b9df5ad1SAndroid Build Coastguard Worker 1634*b9df5ad1SAndroid Build Coastguard Worker for navigable_string in soup.findAll(text=True): 1635*b9df5ad1SAndroid Build Coastguard Worker parent = navigable_string.parent 1636*b9df5ad1SAndroid Build Coastguard Worker 1637*b9df5ad1SAndroid Build Coastguard Worker # Insert each '$text<wbr>$foo' before the old '$text$foo' 1638*b9df5ad1SAndroid Build Coastguard Worker split_by_wbr_list = wbr_filter(navigable_string).split("<wbr>") 1639*b9df5ad1SAndroid Build Coastguard Worker for (split_string, last) in enumerate_with_last(split_by_wbr_list): 1640*b9df5ad1SAndroid Build Coastguard Worker navigable_string.insert_before(split_string) 1641*b9df5ad1SAndroid Build Coastguard Worker 1642*b9df5ad1SAndroid Build Coastguard Worker if not last: 1643*b9df5ad1SAndroid Build Coastguard Worker # Note that 'insert' will move existing tags to this spot 1644*b9df5ad1SAndroid Build Coastguard Worker # so make a new tag instead 1645*b9df5ad1SAndroid Build Coastguard Worker navigable_string.insert_before(wbr_tag()) 1646*b9df5ad1SAndroid Build Coastguard Worker 1647*b9df5ad1SAndroid Build Coastguard Worker # Remove the old unmodified text 1648*b9df5ad1SAndroid Build Coastguard Worker navigable_string.extract() 1649*b9df5ad1SAndroid Build Coastguard Worker 1650*b9df5ad1SAndroid Build Coastguard Worker return soup.decode() 1651*b9df5ad1SAndroid Build Coastguard Worker 1652*b9df5ad1SAndroid Build Coastguard Workerdef copyright_year(): 1653*b9df5ad1SAndroid Build Coastguard Worker return _copyright_year 1654*b9df5ad1SAndroid Build Coastguard Worker 1655*b9df5ad1SAndroid Build Coastguard Workerdef infer_copyright_year_from_source(src_file, default_copyright_year): 1656*b9df5ad1SAndroid Build Coastguard Worker """ 1657*b9df5ad1SAndroid Build Coastguard Worker Opens src_file and tries to infer the copyright year from the file 1658*b9df5ad1SAndroid Build Coastguard Worker if it exists. Returns default_copyright_year if src_file is None, doesn't 1659*b9df5ad1SAndroid Build Coastguard Worker exist, or the copyright year cannot be parsed from the first 15 lines. 1660*b9df5ad1SAndroid Build Coastguard Worker 1661*b9df5ad1SAndroid Build Coastguard Worker Assumption: 1662*b9df5ad1SAndroid Build Coastguard Worker - Copyright text must be in the first 15 lines of the src_file. 1663*b9df5ad1SAndroid Build Coastguard Worker This should almost always be true. 1664*b9df5ad1SAndroid Build Coastguard Worker """ 1665*b9df5ad1SAndroid Build Coastguard Worker if src_file is None: 1666*b9df5ad1SAndroid Build Coastguard Worker return default_copyright_year 1667*b9df5ad1SAndroid Build Coastguard Worker 1668*b9df5ad1SAndroid Build Coastguard Worker if not path.isfile(src_file): 1669*b9df5ad1SAndroid Build Coastguard Worker return default_copyright_year 1670*b9df5ad1SAndroid Build Coastguard Worker 1671*b9df5ad1SAndroid Build Coastguard Worker copyright_pattern = r"^.*Copyright \([Cc]\) (20\d\d) The Android Open Source Project$" 1672*b9df5ad1SAndroid Build Coastguard Worker num_max_lines = 15 1673*b9df5ad1SAndroid Build Coastguard Worker 1674*b9df5ad1SAndroid Build Coastguard Worker with open(src_file, "r") as f: 1675*b9df5ad1SAndroid Build Coastguard Worker for i, line in enumerate(f): 1676*b9df5ad1SAndroid Build Coastguard Worker if i >= num_max_lines: 1677*b9df5ad1SAndroid Build Coastguard Worker break 1678*b9df5ad1SAndroid Build Coastguard Worker 1679*b9df5ad1SAndroid Build Coastguard Worker years = re.findall(copyright_pattern, line.strip()) 1680*b9df5ad1SAndroid Build Coastguard Worker if len(years) > 0: 1681*b9df5ad1SAndroid Build Coastguard Worker return years[0] 1682*b9df5ad1SAndroid Build Coastguard Worker 1683*b9df5ad1SAndroid Build Coastguard Worker return default_copyright_year 1684*b9df5ad1SAndroid Build Coastguard Worker 1685*b9df5ad1SAndroid Build Coastguard Workerdef enum(): 1686*b9df5ad1SAndroid Build Coastguard Worker return _enum 1687*b9df5ad1SAndroid Build Coastguard Worker 1688*b9df5ad1SAndroid Build Coastguard Workerdef first_hal_minor_version(hal_major_version): 1689*b9df5ad1SAndroid Build Coastguard Worker return 2 if hal_major_version == 3 else 0 1690*b9df5ad1SAndroid Build Coastguard Worker 1691*b9df5ad1SAndroid Build Coastguard Workerdef find_all_sections_added_in_hal(root, hal_major_version, hal_minor_version): 1692*b9df5ad1SAndroid Build Coastguard Worker """ 1693*b9df5ad1SAndroid Build Coastguard Worker Find all descendants that are Section or InnerNamespace instances, which 1694*b9df5ad1SAndroid Build Coastguard Worker were added in HIDL HAL version major.minor. The section is defined to be 1695*b9df5ad1SAndroid Build Coastguard Worker added in a HAL version iff the lowest HAL version number of its entries is 1696*b9df5ad1SAndroid Build Coastguard Worker that HAL version. 1697*b9df5ad1SAndroid Build Coastguard Worker 1698*b9df5ad1SAndroid Build Coastguard Worker Args: 1699*b9df5ad1SAndroid Build Coastguard Worker root: a Metadata instance 1700*b9df5ad1SAndroid Build Coastguard Worker hal_major/minor_version: HAL version numbers 1701*b9df5ad1SAndroid Build Coastguard Worker 1702*b9df5ad1SAndroid Build Coastguard Worker Returns: 1703*b9df5ad1SAndroid Build Coastguard Worker A list of Section/InnerNamespace instances 1704*b9df5ad1SAndroid Build Coastguard Worker 1705*b9df5ad1SAndroid Build Coastguard Worker Remarks: 1706*b9df5ad1SAndroid Build Coastguard Worker These are known as "sections" in the generated C code. 1707*b9df5ad1SAndroid Build Coastguard Worker """ 1708*b9df5ad1SAndroid Build Coastguard Worker all_sections = find_all_sections(root) 1709*b9df5ad1SAndroid Build Coastguard Worker new_sections = [] 1710*b9df5ad1SAndroid Build Coastguard Worker for section in all_sections: 1711*b9df5ad1SAndroid Build Coastguard Worker min_major_version = None 1712*b9df5ad1SAndroid Build Coastguard Worker min_minor_version = None 1713*b9df5ad1SAndroid Build Coastguard Worker for entry in remove_hal_non_visible(find_unique_entries(section)): 1714*b9df5ad1SAndroid Build Coastguard Worker min_major_version = (min_major_version or entry.hal_major_version) 1715*b9df5ad1SAndroid Build Coastguard Worker min_minor_version = (min_minor_version or entry.hal_minor_version) 1716*b9df5ad1SAndroid Build Coastguard Worker if entry.hal_major_version < min_major_version or \ 1717*b9df5ad1SAndroid Build Coastguard Worker (entry.hal_major_version == min_major_version and entry.hal_minor_version < min_minor_version): 1718*b9df5ad1SAndroid Build Coastguard Worker min_minor_version = entry.hal_minor_version 1719*b9df5ad1SAndroid Build Coastguard Worker min_major_version = entry.hal_major_version 1720*b9df5ad1SAndroid Build Coastguard Worker if min_major_version == hal_major_version and min_minor_version == hal_minor_version: 1721*b9df5ad1SAndroid Build Coastguard Worker new_sections.append(section) 1722*b9df5ad1SAndroid Build Coastguard Worker return new_sections 1723*b9df5ad1SAndroid Build Coastguard Worker 1724*b9df5ad1SAndroid Build Coastguard Workerdef find_first_older_used_hal_version(section, hal_major_version, hal_minor_version): 1725*b9df5ad1SAndroid Build Coastguard Worker hal_version = (0, 0) 1726*b9df5ad1SAndroid Build Coastguard Worker for v in section.hal_versions: 1727*b9df5ad1SAndroid Build Coastguard Worker if (v[0] > hal_version[0] or (v[0] == hal_version[0] and v[1] > hal_version[1])) and \ 1728*b9df5ad1SAndroid Build Coastguard Worker (v[0] < hal_major_version or (v[0] == hal_major_version and v[1] < hal_minor_version)): 1729*b9df5ad1SAndroid Build Coastguard Worker hal_version = v 1730*b9df5ad1SAndroid Build Coastguard Worker return hal_version 1731*b9df5ad1SAndroid Build Coastguard Worker 1732*b9df5ad1SAndroid Build Coastguard Worker# Some exceptions need to be made regarding enum value identifiers in AIDL. 1733*b9df5ad1SAndroid Build Coastguard Worker# Process them here. 1734*b9df5ad1SAndroid Build Coastguard Workerdef aidl_enum_value_name(name): 1735*b9df5ad1SAndroid Build Coastguard Worker if name == 'ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5': 1736*b9df5ad1SAndroid Build Coastguard Worker name = 'ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE' 1737*b9df5ad1SAndroid Build Coastguard Worker return name 1738*b9df5ad1SAndroid Build Coastguard Worker 1739*b9df5ad1SAndroid Build Coastguard Workerdef aidl_enum_values(entry): 1740*b9df5ad1SAndroid Build Coastguard Worker ignoreList = [ 1741*b9df5ad1SAndroid Build Coastguard Worker 'ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END', 1742*b9df5ad1SAndroid Build Coastguard Worker 'ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8' 1743*b9df5ad1SAndroid Build Coastguard Worker ] 1744*b9df5ad1SAndroid Build Coastguard Worker return [ 1745*b9df5ad1SAndroid Build Coastguard Worker val for val in entry.enum.values if '%s_%s'%(csym(entry.name), val.name) not in ignoreList 1746*b9df5ad1SAndroid Build Coastguard Worker ] 1747*b9df5ad1SAndroid Build Coastguard Worker 1748*b9df5ad1SAndroid Build Coastguard Workerdef java_symbol_for_aconfig_flag(flag_name): 1749*b9df5ad1SAndroid Build Coastguard Worker """ 1750*b9df5ad1SAndroid Build Coastguard Worker Returns the java symbol for a give aconfig flag. This means converting 1751*b9df5ad1SAndroid Build Coastguard Worker snake_case to lower camelCase. For example: The aconfig flag 1752*b9df5ad1SAndroid Build Coastguard Worker 'camera_ae_mode_low_light_boost' becomes 'cameraAeModeLowLightBoost'. 1753*b9df5ad1SAndroid Build Coastguard Worker 1754*b9df5ad1SAndroid Build Coastguard Worker Args: 1755*b9df5ad1SAndroid Build Coastguard Worker flag_name: str. aconfig flag in snake_case 1756*b9df5ad1SAndroid Build Coastguard Worker 1757*b9df5ad1SAndroid Build Coastguard Worker Return: 1758*b9df5ad1SAndroid Build Coastguard Worker Java symbol for the a config flag. 1759*b9df5ad1SAndroid Build Coastguard Worker """ 1760*b9df5ad1SAndroid Build Coastguard Worker camel_case = "".join([t.capitalize() for t in flag_name.split("_")]) 1761*b9df5ad1SAndroid Build Coastguard Worker # first character should be lowercase 1762*b9df5ad1SAndroid Build Coastguard Worker return camel_case[0].lower() + camel_case[1:] 1763