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 && ` + 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") 48 49 xsdcCppRule = pctx.StaticRule("xsdcCppRule", blueprint.RuleParams{ 50 Command: `rm -rf "${outDir}" && ` + 51 `${xsdcCmd} $in -p $pkgName -o ${outDir} -c`, 52 CommandDeps: []string{"${xsdcCmd}", "${config.SoongZipCmd}"}, 53 Description: "xsdc C++ ${in} => ${out}", 54 }, "pkgName", "outDir") 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} 67 68type xsdConfig struct { 69 android.ModuleBase 70 71 properties xsdConfigProperties 72 73 genOutputDir android.Path 74 genOutputs_j android.WritablePath 75 genOutputs_c android.WritablePath 76 genOutputs_h android.WritablePath 77 78 docsPath android.Path 79 80 xsdConfigPath android.OptionalPath 81 genOutputs android.Paths 82} 83 84var _ android.SourceFileProducer = (*xsdConfig)(nil) 85 86type ApiToCheck struct { 87 Api_file *string 88 Removed_api_file *string 89 Args *string 90} 91 92type CheckApi struct { 93 Last_released ApiToCheck 94 Current ApiToCheck 95} 96type DroidstubsProperties struct { 97 Name *string 98 Installable *bool 99 Srcs []string 100 Sdk_version *string 101 Args *string 102 Api_filename *string 103 Removed_api_filename *string 104 Check_api CheckApi 105} 106 107func (module *xsdConfig) GeneratedSourceFiles() android.Paths { 108 return android.Paths{module.genOutputs_c} 109} 110 111func (module *xsdConfig) Srcs() android.Paths { 112 return append(module.genOutputs, module.genOutputs_j) 113} 114 115func (module *xsdConfig) GeneratedDeps() android.Paths { 116 return android.Paths{module.genOutputs_h} 117} 118 119func (module *xsdConfig) GeneratedHeaderDirs() android.Paths { 120 return android.Paths{module.genOutputDir} 121} 122 123func (module *xsdConfig) DepsMutator(ctx android.BottomUpMutatorContext) { 124 android.ExtractSourcesDeps(ctx, module.properties.Srcs) 125} 126 127func (module *xsdConfig) generateXsdConfig(ctx android.ModuleContext) { 128 if !module.xsdConfigPath.Valid() { 129 return 130 } 131 132 output := android.PathForModuleGen(ctx, module.Name()+".xsd") 133 module.genOutputs = append(module.genOutputs, output) 134 135 ctx.ModuleBuild(pctx, android.ModuleBuildParams{ 136 Rule: xsdConfigRule, 137 Input: module.xsdConfigPath.Path(), 138 Output: output, 139 Args: map[string]string{ 140 "output": output.String(), 141 }, 142 }) 143} 144 145func (module *xsdConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) { 146 if len(module.properties.Srcs) != 1 { 147 ctx.PropertyErrorf("srcs", "xsd_config must be one src") 148 } 149 150 ctx.VisitDirectDeps(func(to android.Module) { 151 if doc, ok := to.(java.ApiFilePath); ok { 152 module.docsPath = doc.ApiFilePath() 153 } 154 }) 155 156 srcFiles := ctx.ExpandSources(module.properties.Srcs, nil) 157 xsdFile := srcFiles[0] 158 159 pkgName := *module.properties.Package_name 160 filenameStem := strings.Replace(pkgName, ".", "_", -1) 161 162 module.genOutputs_j = android.PathForModuleGen(ctx, "java", filenameStem+"_xsdcgen.srcjar") 163 164 ctx.Build(pctx, android.BuildParams{ 165 Rule: xsdcJavaRule, 166 Description: "xsdc " + xsdFile.String(), 167 Input: xsdFile, 168 Implicit: module.docsPath, 169 Output: module.genOutputs_j, 170 Args: map[string]string{ 171 "pkgName": pkgName, 172 }, 173 }) 174 175 module.genOutputs_c = android.PathForModuleGen(ctx, "cpp", filenameStem+".cpp") 176 module.genOutputs_h = android.PathForModuleGen(ctx, "cpp", "include/"+filenameStem+".h") 177 module.genOutputDir = android.PathForModuleGen(ctx, "cpp", "include") 178 179 ctx.Build(pctx, android.BuildParams{ 180 Rule: xsdcCppRule, 181 Description: "xsdc " + xsdFile.String(), 182 Input: xsdFile, 183 Implicit: module.docsPath, 184 Output: module.genOutputs_c, 185 ImplicitOutput: module.genOutputs_h, 186 Args: map[string]string{ 187 "pkgName": pkgName, 188 "outDir": android.PathForModuleGen(ctx, "cpp").String(), 189 }, 190 }) 191 module.xsdConfigPath = android.ExistentPathForSource(ctx, xsdFile.String()) 192 module.generateXsdConfig(ctx) 193} 194 195func xsdConfigMutator(mctx android.TopDownMutatorContext) { 196 if module, ok := mctx.Module().(*xsdConfig); ok { 197 name := module.BaseModuleName() 198 199 args := " --stub-packages " + *module.properties.Package_name + 200 " --hide MissingPermission --hide BroadcastBehavior" + 201 " --hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol" + 202 " --hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo" 203 204 api_dir := proptools.StringDefault(module.properties.Api_dir, "api") 205 206 currentApiFileName := filepath.Join(api_dir, "current.txt") 207 removedApiFileName := filepath.Join(api_dir, "removed.txt") 208 209 check_api := CheckApi{} 210 211 check_api.Current.Api_file = proptools.StringPtr(currentApiFileName) 212 check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName) 213 214 check_api.Last_released.Api_file = proptools.StringPtr( 215 filepath.Join(api_dir, "last_current.txt")) 216 check_api.Last_released.Removed_api_file = proptools.StringPtr( 217 filepath.Join(api_dir, "last_removed.txt")) 218 219 mctx.CreateModule(java.DroidstubsFactory, &DroidstubsProperties{ 220 Name: proptools.StringPtr(name + ".docs"), 221 Srcs: []string{":" + name}, 222 Args: proptools.StringPtr(args), 223 Api_filename: proptools.StringPtr(currentApiFileName), 224 Removed_api_filename: proptools.StringPtr(removedApiFileName), 225 Check_api: check_api, 226 Installable: proptools.BoolPtr(false), 227 Sdk_version: proptools.StringPtr("core_platform"), 228 }) 229 } 230} 231 232func xsdConfigFactory() android.Module { 233 module := &xsdConfig{} 234 module.AddProperties(&module.properties) 235 android.InitAndroidModule(module) 236 237 return module 238} 239