1// Copyright 2018 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package xsdc 16 17import ( 18 "android/soong/android" 19 "android/soong/java" 20 "path/filepath" 21 "strings" 22 23 "github.com/google/blueprint" 24 "github.com/google/blueprint/proptools" 25) 26 27func init() { 28 pctx.Import("android/soong/java/config") 29 android.RegisterModuleType("xsd_config", xsdConfigFactory) 30 31 android.PreArchMutators(func(ctx android.RegisterMutatorsContext) { 32 ctx.TopDown("xsd_config", xsdConfigMutator).Parallel() 33 }) 34} 35 36var ( 37 pctx = android.NewPackageContext("android/xsdc") 38 39 xsdc = pctx.HostBinToolVariable("xsdcCmd", "xsdc") 40 xsdcJavaRule = pctx.StaticRule("xsdcJavaRule", blueprint.RuleParams{ 41 Command: `rm -rf "${out}.temp" && mkdir -p "${out}.temp" && ` + 42 `${xsdcCmd} $in -p $pkgName -o ${out}.temp -j $args && ` + 43 `${config.SoongZipCmd} -jar -o ${out} -C ${out}.temp -D ${out}.temp && ` + 44 `rm -rf ${out}.temp`, 45 CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"}, 46 Description: "xsdc Java ${in} => ${out}", 47 }, "pkgName", "args") 48 49 xsdcCppRule = pctx.StaticRule("xsdcCppRule", blueprint.RuleParams{ 50 Command: `rm -rf "${outDir}" && ` + 51 `${xsdcCmd} $in -p $pkgName -o ${outDir} -c $args`, 52 CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"}, 53 Description: "xsdc C++ ${in} => ${out}", 54 }, "pkgName", "outDir", "args") 55 56 xsdConfigRule = pctx.StaticRule("xsdConfigRule", blueprint.RuleParams{ 57 Command: "cp -f ${in} ${output}", 58 Description: "copy the xsd file: ${in} => ${output}", 59 }, "output") 60) 61 62type xsdConfigProperties struct { 63 Srcs []string 64 Package_name *string 65 Api_dir *string 66 Gen_writer *bool 67} 68 69type xsdConfig struct { 70 android.ModuleBase 71 72 properties xsdConfigProperties 73 74 genOutputDir android.Path 75 genOutputs_j android.WritablePath 76 genOutputs_c android.WritablePath 77 genOutputs_h android.WritablePath 78 79 docsPath android.Path 80 81 xsdConfigPath android.OptionalPath 82 genOutputs android.Paths 83} 84 85var _ android.SourceFileProducer = (*xsdConfig)(nil) 86 87type ApiToCheck struct { 88 Api_file *string 89 Removed_api_file *string 90 Args *string 91} 92 93type CheckApi struct { 94 Last_released ApiToCheck 95 Current ApiToCheck 96} 97type DroidstubsProperties struct { 98 Name *string 99 Installable *bool 100 Srcs []string 101 Sdk_version *string 102 Args *string 103 Api_filename *string 104 Removed_api_filename *string 105 Check_api CheckApi 106} 107 108func (module *xsdConfig) GeneratedSourceFiles() android.Paths { 109 return android.Paths{module.genOutputs_c} 110} 111 112func (module *xsdConfig) Srcs() android.Paths { 113 return append(module.genOutputs, module.genOutputs_j) 114} 115 116func (module *xsdConfig) GeneratedDeps() android.Paths { 117 return android.Paths{module.genOutputs_h} 118} 119 120func (module *xsdConfig) GeneratedHeaderDirs() android.Paths { 121 return android.Paths{module.genOutputDir} 122} 123 124func (module *xsdConfig) DepsMutator(ctx android.BottomUpMutatorContext) { 125 android.ExtractSourcesDeps(ctx, module.properties.Srcs) 126} 127 128func (module *xsdConfig) generateXsdConfig(ctx android.ModuleContext) { 129 if !module.xsdConfigPath.Valid() { 130 return 131 } 132 133 output := android.PathForModuleGen(ctx, module.Name()+".xsd") 134 module.genOutputs = append(module.genOutputs, output) 135 136 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 137 Rule: xsdConfigRule, 138 Input: module.xsdConfigPath.Path(), 139 Output: output, 140 Args: map[string]string{ 141 "output": output.String(), 142 }, 143 }) 144} 145 146func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) { 147 if len(module.properties.Srcs) != 1 { 148 ctx.PropertyErrorf("srcs", "xsd_config must be one src") 149 } 150 151 ctx.VisitDirectDeps(func(to android.Module) { 152 if doc, ok := to.(java.ApiFilePath); ok { 153 module.docsPath = doc.ApiFilePath() 154 } 155 }) 156 157 srcFiles := ctx.ExpandSources(module.properties.Srcs, nil) 158 xsdFile := srcFiles[0] 159 160 pkgName := *module.properties.Package_name 161 filenameStem := strings.Replace(pkgName, ".", "_", -1) 162 163 args := "" 164 if proptools.Bool(module.properties.Gen_writer) { 165 args = "-w" 166 } 167 168 module.genOutputs_j = android.PathForModuleGen(ctx, "java", filenameStem+"_xsdcgen.srcjar") 169 170 ctx.Build(pctx, android.BuildParams{ 171 Rule: xsdcJavaRule, 172 Description: "xsdc " + xsdFile.String(), 173 Input: xsdFile, 174 Implicit: module.docsPath, 175 Output: module.genOutputs_j, 176 Args: map[string]string{ 177 "pkgName": pkgName, 178 "args": args, 179 }, 180 }) 181 182 module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp") 183 module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h") 184 module.genOutputDir = android.PathForModuleGen(ctx, "cpp", "include") 185 186 ctx.Build(pctx, android.BuildParams{ 187 Rule: xsdcCppRule, 188 Description: "xsdc " + xsdFile.String(), 189 Input: xsdFile, 190 Implicit: module.docsPath, 191 Output: module.genOutputs_c, 192 ImplicitOutput: module.genOutputs_h, 193 Args: map[string]string{ 194 "pkgName": pkgName, 195 "outDir": android.PathForModuleGen(ctx, "cpp").String(), 196 "args": args, 197 }, 198 }) 199 module.xsdConfigPath = android.ExistentPathForSource(ctx, xsdFile.String()) 200 module.generateXsdConfig(ctx) 201} 202 203func xsdConfigMutator(mctx android.TopDownMutatorContext) { 204 if module, ok := mctx.Module().(*xsdConfig); ok { 205 name := module.BaseModuleName() 206 207 args := " --stub-packages " + *module.properties.Package_name + 208 " --hide MissingPermission --hide BroadcastBehavior" + 209 " --hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol" + 210 " --hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo" 211 212 api_dir := proptools.StringDefault(module.properties.Api_dir, "api") 213 214 currentApiFileName := filepath.Join(api_dir, "current.txt") 215 removedApiFileName := filepath.Join(api_dir, "removed.txt") 216 217 check_api := CheckApi{} 218 219 check_api.Current.Api_file = proptools.StringPtr(currentApiFileName) 220 check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName) 221 222 check_api.Last_released.Api_file = proptools.StringPtr( 223 filepath.Join(api_dir, "last_current.txt")) 224 check_api.Last_released.Removed_api_file = proptools.StringPtr( 225 filepath.Join(api_dir, "last_removed.txt")) 226 227 mctx.CreateModule(java.DroidstubsFactory, &DroidstubsProperties{ 228 Name: proptools.StringPtr(name + ".docs"), 229 Srcs: []string{":" + name}, 230 Args: proptools.StringPtr(args), 231 Api_filename: proptools.StringPtr(currentApiFileName), 232 Removed_api_filename: proptools.StringPtr(removedApiFileName), 233 Check_api: check_api, 234 Installable: proptools.BoolPtr(false), 235 Sdk_version: proptools.StringPtr("core_platform"), 236 }) 237 } 238} 239 240func xsdConfigFactory() android.Module { 241 module := &xsdConfig{} 242 module.AddProperties(&module.properties) 243 android.InitAndroidModule(module) 244 245 return module 246} 247