| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 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 |  | 
|  | 15 | package dexpreopt | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "encoding/json" | 
|  | 19 | "io/ioutil" | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 20 | "strings" | 
| Colin Cross | 74ba962 | 2019-02-11 15:11:14 -0800 | [diff] [blame] | 21 |  | 
|  | 22 | "android/soong/android" | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 23 | ) | 
|  | 24 |  | 
|  | 25 | // GlobalConfig stores the configuration for dex preopting set by the product | 
|  | 26 | type GlobalConfig struct { | 
|  | 27 | DefaultNoStripping bool // don't strip dex files by default | 
|  | 28 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 29 | DisablePreopt        bool     // disable preopt for all modules | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 30 | DisablePreoptModules []string // modules with preopt disabled by product-specific config | 
|  | 31 |  | 
|  | 32 | OnlyPreoptBootImageAndSystemServer bool // only preopt jars in the boot image or system server | 
|  | 33 |  | 
| Nicolas Geoffray | 72892f1 | 2019-02-22 15:34:40 +0000 | [diff] [blame] | 34 | GenerateApexImage bool // generate an extra boot image only containing jars from the runtime apex | 
|  | 35 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 36 | HasSystemOther        bool     // store odex files that match PatternsOnSystemOther on the system_other partition | 
|  | 37 | PatternsOnSystemOther []string // patterns (using '%' to denote a prefix match) to put odex on the system_other partition | 
|  | 38 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 39 | DisableGenerateProfile bool   // don't generate profiles | 
|  | 40 | ProfileDir             string // directory to find profiles in | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 41 |  | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 42 | BootJars []string // modules for jars that form the boot class path | 
| Vladimir Marko | d2ee532 | 2018-12-19 17:57:57 +0000 | [diff] [blame] | 43 |  | 
| Nicolas Geoffray | 39fe574 | 2019-02-20 10:00:47 +0000 | [diff] [blame] | 44 | RuntimeApexJars               []string // modules for jars that are in the runtime apex | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 45 | ProductUpdatableBootModules   []string | 
|  | 46 | ProductUpdatableBootLocations []string | 
|  | 47 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 48 | SystemServerJars []string // jars that form the system server | 
|  | 49 | SystemServerApps []string // apps that are loaded into system server | 
|  | 50 | SpeedApps        []string // apps that should be speed optimized | 
|  | 51 |  | 
|  | 52 | PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified | 
|  | 53 |  | 
|  | 54 | DefaultCompilerFilter      string // default compiler filter to pass to dex2oat, overridden by --compiler-filter= in module-specific dex2oat flags | 
|  | 55 | SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars | 
|  | 56 |  | 
| Nicolas Geoffray | fa6e9ec | 2019-02-12 13:12:16 +0000 | [diff] [blame] | 57 | GenerateDMFiles     bool // generate Dex Metadata files | 
|  | 58 | NeverAllowStripping bool // whether stripping should not be done - used as build time check to make sure dex files are always available | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 59 |  | 
|  | 60 | NoDebugInfo                 bool // don't generate debug info by default | 
|  | 61 | AlwaysSystemServerDebugInfo bool // always generate mini debug info for system server modules (overrides NoDebugInfo=true) | 
|  | 62 | NeverSystemServerDebugInfo  bool // never generate mini debug info for system server modules (overrides NoDebugInfo=false) | 
|  | 63 | AlwaysOtherDebugInfo        bool // always generate mini debug info for non-system server modules (overrides NoDebugInfo=true) | 
|  | 64 | NeverOtherDebugInfo         bool // never generate mini debug info for non-system server modules (overrides NoDebugInfo=true) | 
|  | 65 |  | 
|  | 66 | MissingUsesLibraries []string // libraries that may be listed in OptionalUsesLibraries but will not be installed by the product | 
|  | 67 |  | 
|  | 68 | IsEng        bool // build is a eng variant | 
|  | 69 | SanitizeLite bool // build is the second phase of a SANITIZE_LITE build | 
|  | 70 |  | 
|  | 71 | DefaultAppImages bool // build app images (TODO: .art files?) by default | 
|  | 72 |  | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 73 | Dex2oatXmx string // max heap size for dex2oat | 
|  | 74 | Dex2oatXms string // initial heap size for dex2oat | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 75 |  | 
|  | 76 | EmptyDirectory string // path to an empty directory | 
|  | 77 |  | 
| Colin Cross | 74ba962 | 2019-02-11 15:11:14 -0800 | [diff] [blame] | 78 | CpuVariant             map[android.ArchType]string // cpu variant for each architecture | 
|  | 79 | InstructionSetFeatures map[android.ArchType]string // instruction set for each architecture | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 80 |  | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 81 | // Only used for boot image | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 82 | DirtyImageObjects      android.OptionalPath // path to a dirty-image-objects file | 
|  | 83 | PreloadedClasses       android.OptionalPath // path to a preloaded-classes file | 
|  | 84 | BootImageProfiles      android.Paths        // path to a boot-image-profile.txt file | 
|  | 85 | UseProfileForBootImage bool                 // whether a profile should be used to compile the boot image | 
|  | 86 | BootFlags              string               // extra flags to pass to dex2oat for the boot image | 
|  | 87 | Dex2oatImageXmx        string               // max heap size for dex2oat for the boot image | 
|  | 88 | Dex2oatImageXms        string               // initial heap size for dex2oat for the boot image | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 89 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 90 | Tools Tools // paths to tools possibly used by the generated commands | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | // Tools contains paths to tools possibly used by the generated commands.  If you add a new tool here you MUST add it | 
|  | 94 | // to the order-only dependency list in DEXPREOPT_GEN_DEPS. | 
|  | 95 | type Tools struct { | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 96 | Profman  android.Path | 
|  | 97 | Dex2oat  android.Path | 
|  | 98 | Aapt     android.Path | 
|  | 99 | SoongZip android.Path | 
|  | 100 | Zip2zip  android.Path | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 101 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 102 | VerifyUsesLibraries android.Path | 
|  | 103 | ConstructContext    android.Path | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 104 | } | 
|  | 105 |  | 
|  | 106 | type ModuleConfig struct { | 
| Victor Hsieh | d181c8b | 2019-01-29 13:00:33 -0800 | [diff] [blame] | 107 | Name            string | 
|  | 108 | DexLocation     string // dex location on device | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 109 | BuildPath       android.OutputPath | 
|  | 110 | DexPath         android.Path | 
| Victor Hsieh | d181c8b | 2019-01-29 13:00:33 -0800 | [diff] [blame] | 111 | UncompressedDex bool | 
|  | 112 | HasApkLibraries bool | 
|  | 113 | PreoptFlags     []string | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 114 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 115 | ProfileClassListing  android.OptionalPath | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 116 | ProfileIsTextListing bool | 
|  | 117 |  | 
|  | 118 | EnforceUsesLibraries  bool | 
|  | 119 | OptionalUsesLibraries []string | 
|  | 120 | UsesLibraries         []string | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 121 | LibraryPaths          map[string]android.Path | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 122 |  | 
| Colin Cross | 74ba962 | 2019-02-11 15:11:14 -0800 | [diff] [blame] | 123 | Archs           []android.ArchType | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 124 | DexPreoptImages []android.Path | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 125 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 126 | PreoptBootClassPathDexFiles     android.Paths // file paths of boot class path files | 
|  | 127 | PreoptBootClassPathDexLocations []string      // virtual locations of boot class path files | 
| Colin Cross | 800fe13 | 2019-02-11 14:21:24 -0800 | [diff] [blame] | 128 |  | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 129 | PreoptExtractedApk bool // Overrides OnlyPreoptModules | 
|  | 130 |  | 
|  | 131 | NoCreateAppImage    bool | 
|  | 132 | ForceCreateAppImage bool | 
|  | 133 |  | 
|  | 134 | PresignedPrebuilt bool | 
|  | 135 |  | 
| Colin Cross | 8c6d250 | 2019-01-09 21:09:14 -0800 | [diff] [blame] | 136 | NoStripping     bool | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 137 | StripInputPath  android.Path | 
|  | 138 | StripOutputPath android.WritablePath | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 139 | } | 
|  | 140 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 141 | func constructPath(ctx android.PathContext, path string) android.Path { | 
|  | 142 | buildDirPrefix := ctx.Config().BuildDir() + "/" | 
|  | 143 | if path == "" { | 
|  | 144 | return nil | 
|  | 145 | } else if strings.HasPrefix(path, buildDirPrefix) { | 
|  | 146 | return android.PathForOutput(ctx, strings.TrimPrefix(path, buildDirPrefix)) | 
|  | 147 | } else { | 
|  | 148 | return android.PathForSource(ctx, path) | 
|  | 149 | } | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 150 | } | 
|  | 151 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 152 | func constructPaths(ctx android.PathContext, paths []string) android.Paths { | 
|  | 153 | var ret android.Paths | 
|  | 154 | for _, path := range paths { | 
|  | 155 | ret = append(ret, constructPath(ctx, path)) | 
|  | 156 | } | 
|  | 157 | return ret | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 158 | } | 
|  | 159 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 160 | func constructPathMap(ctx android.PathContext, paths map[string]string) map[string]android.Path { | 
|  | 161 | ret := map[string]android.Path{} | 
|  | 162 | for key, path := range paths { | 
|  | 163 | ret[key] = constructPath(ctx, path) | 
|  | 164 | } | 
|  | 165 | return ret | 
|  | 166 | } | 
|  | 167 |  | 
|  | 168 | func constructWritablePath(ctx android.PathContext, path string) android.WritablePath { | 
|  | 169 | if path == "" { | 
|  | 170 | return nil | 
|  | 171 | } | 
|  | 172 | return constructPath(ctx, path).(android.WritablePath) | 
|  | 173 | } | 
|  | 174 |  | 
|  | 175 | // LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig struct.  It is used directly in Soong | 
|  | 176 | // and in dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by Make. | 
|  | 177 | func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, error) { | 
|  | 178 | type GlobalJSONConfig struct { | 
|  | 179 | GlobalConfig | 
|  | 180 |  | 
|  | 181 | // Copies of entries in GlobalConfig that are not constructable without extra parameters.  They will be | 
|  | 182 | // used to construct the real value manually below. | 
|  | 183 | DirtyImageObjects string | 
|  | 184 | PreloadedClasses  string | 
|  | 185 | BootImageProfiles []string | 
|  | 186 |  | 
|  | 187 | Tools struct { | 
|  | 188 | Profman  string | 
|  | 189 | Dex2oat  string | 
|  | 190 | Aapt     string | 
|  | 191 | SoongZip string | 
|  | 192 | Zip2zip  string | 
|  | 193 |  | 
|  | 194 | VerifyUsesLibraries string | 
|  | 195 | ConstructContext    string | 
|  | 196 | } | 
|  | 197 | } | 
|  | 198 |  | 
|  | 199 | config := GlobalJSONConfig{} | 
|  | 200 | err := loadConfig(ctx, path, &config) | 
|  | 201 | if err != nil { | 
|  | 202 | return config.GlobalConfig, err | 
|  | 203 | } | 
|  | 204 |  | 
|  | 205 | // Construct paths that require a PathContext. | 
|  | 206 | config.GlobalConfig.DirtyImageObjects = android.OptionalPathForPath(constructPath(ctx, config.DirtyImageObjects)) | 
|  | 207 | config.GlobalConfig.PreloadedClasses = android.OptionalPathForPath(constructPath(ctx, config.PreloadedClasses)) | 
|  | 208 | config.GlobalConfig.BootImageProfiles = constructPaths(ctx, config.BootImageProfiles) | 
|  | 209 |  | 
|  | 210 | config.GlobalConfig.Tools.Profman = constructPath(ctx, config.Tools.Profman) | 
|  | 211 | config.GlobalConfig.Tools.Dex2oat = constructPath(ctx, config.Tools.Dex2oat) | 
|  | 212 | config.GlobalConfig.Tools.Aapt = constructPath(ctx, config.Tools.Aapt) | 
|  | 213 | config.GlobalConfig.Tools.SoongZip = constructPath(ctx, config.Tools.SoongZip) | 
|  | 214 | config.GlobalConfig.Tools.Zip2zip = constructPath(ctx, config.Tools.Zip2zip) | 
|  | 215 | config.GlobalConfig.Tools.VerifyUsesLibraries = constructPath(ctx, config.Tools.VerifyUsesLibraries) | 
|  | 216 | config.GlobalConfig.Tools.ConstructContext = constructPath(ctx, config.Tools.ConstructContext) | 
|  | 217 |  | 
|  | 218 | return config.GlobalConfig, nil | 
|  | 219 | } | 
|  | 220 |  | 
|  | 221 | // LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct.  It is not used in Soong, which | 
|  | 222 | // receives a ModuleConfig struct directly from java/dexpreopt.go.  It is used in dexpreopt_gen called from oMake to | 
|  | 223 | // read the module dexpreopt.config written by Make. | 
|  | 224 | func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error) { | 
|  | 225 | type ModuleJSONConfig struct { | 
|  | 226 | ModuleConfig | 
|  | 227 |  | 
|  | 228 | // Copies of entries in ModuleConfig that are not constructable without extra parameters.  They will be | 
|  | 229 | // used to construct the real value manually below. | 
|  | 230 | BuildPath                   string | 
|  | 231 | DexPath                     string | 
|  | 232 | ProfileClassListing         string | 
|  | 233 | LibraryPaths                map[string]string | 
|  | 234 | DexPreoptImages             []string | 
|  | 235 | PreoptBootClassPathDexFiles []string | 
|  | 236 | StripInputPath              string | 
|  | 237 | StripOutputPath             string | 
|  | 238 | } | 
|  | 239 |  | 
|  | 240 | config := ModuleJSONConfig{} | 
|  | 241 |  | 
|  | 242 | err := loadConfig(ctx, path, &config) | 
|  | 243 | if err != nil { | 
|  | 244 | return config.ModuleConfig, err | 
|  | 245 | } | 
|  | 246 |  | 
|  | 247 | // Construct paths that require a PathContext. | 
|  | 248 | config.ModuleConfig.BuildPath = constructPath(ctx, config.BuildPath).(android.OutputPath) | 
|  | 249 | config.ModuleConfig.DexPath = constructPath(ctx, config.DexPath) | 
|  | 250 | config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing)) | 
|  | 251 | config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths) | 
|  | 252 | config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages) | 
|  | 253 | config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles) | 
|  | 254 | config.ModuleConfig.StripInputPath = constructPath(ctx, config.StripInputPath) | 
|  | 255 | config.ModuleConfig.StripOutputPath = constructWritablePath(ctx, config.StripOutputPath) | 
|  | 256 |  | 
|  | 257 | return config.ModuleConfig, nil | 
|  | 258 | } | 
|  | 259 |  | 
|  | 260 | func loadConfig(ctx android.PathContext, path string, config interface{}) error { | 
|  | 261 | r, err := ctx.Fs().Open(path) | 
|  | 262 | if err != nil { | 
|  | 263 | return err | 
|  | 264 | } | 
|  | 265 | defer r.Close() | 
|  | 266 |  | 
|  | 267 | data, err := ioutil.ReadAll(r) | 
| Colin Cross | 43f08db | 2018-11-12 10:13:39 -0800 | [diff] [blame] | 268 | if err != nil { | 
|  | 269 | return err | 
|  | 270 | } | 
|  | 271 |  | 
|  | 272 | err = json.Unmarshal(data, config) | 
|  | 273 | if err != nil { | 
|  | 274 | return err | 
|  | 275 | } | 
|  | 276 |  | 
|  | 277 | return nil | 
|  | 278 | } | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 279 |  | 
|  | 280 | func GlobalConfigForTests(ctx android.PathContext) GlobalConfig { | 
|  | 281 | return GlobalConfig{ | 
|  | 282 | DefaultNoStripping:                 false, | 
|  | 283 | DisablePreopt:                      false, | 
|  | 284 | DisablePreoptModules:               nil, | 
|  | 285 | OnlyPreoptBootImageAndSystemServer: false, | 
|  | 286 | HasSystemOther:                     false, | 
|  | 287 | PatternsOnSystemOther:              nil, | 
|  | 288 | DisableGenerateProfile:             false, | 
|  | 289 | ProfileDir:                         "", | 
|  | 290 | BootJars:                           nil, | 
|  | 291 | RuntimeApexJars:                    nil, | 
|  | 292 | ProductUpdatableBootModules:        nil, | 
|  | 293 | ProductUpdatableBootLocations:      nil, | 
|  | 294 | SystemServerJars:                   nil, | 
|  | 295 | SystemServerApps:                   nil, | 
|  | 296 | SpeedApps:                          nil, | 
|  | 297 | PreoptFlags:                        nil, | 
|  | 298 | DefaultCompilerFilter:              "", | 
|  | 299 | SystemServerCompilerFilter:         "", | 
|  | 300 | GenerateDMFiles:                    false, | 
|  | 301 | NeverAllowStripping:                false, | 
|  | 302 | NoDebugInfo:                        false, | 
|  | 303 | AlwaysSystemServerDebugInfo:        false, | 
|  | 304 | NeverSystemServerDebugInfo:         false, | 
|  | 305 | AlwaysOtherDebugInfo:               false, | 
|  | 306 | NeverOtherDebugInfo:                false, | 
|  | 307 | MissingUsesLibraries:               nil, | 
|  | 308 | IsEng:                              false, | 
|  | 309 | SanitizeLite:                       false, | 
|  | 310 | DefaultAppImages:                   false, | 
|  | 311 | Dex2oatXmx:                         "", | 
|  | 312 | Dex2oatXms:                         "", | 
|  | 313 | EmptyDirectory:                     "empty_dir", | 
|  | 314 | CpuVariant:                         nil, | 
|  | 315 | InstructionSetFeatures:             nil, | 
|  | 316 | DirtyImageObjects:                  android.OptionalPath{}, | 
|  | 317 | PreloadedClasses:                   android.OptionalPath{}, | 
|  | 318 | BootImageProfiles:                  nil, | 
|  | 319 | UseProfileForBootImage:             false, | 
|  | 320 | BootFlags:                          "", | 
|  | 321 | Dex2oatImageXmx:                    "", | 
|  | 322 | Dex2oatImageXms:                    "", | 
|  | 323 | Tools: Tools{ | 
|  | 324 | Profman:             android.PathForTesting("profman"), | 
|  | 325 | Dex2oat:             android.PathForTesting("dex2oat"), | 
|  | 326 | Aapt:                android.PathForTesting("aapt"), | 
|  | 327 | SoongZip:            android.PathForTesting("soong_zip"), | 
|  | 328 | Zip2zip:             android.PathForTesting("zip2zip"), | 
|  | 329 | VerifyUsesLibraries: android.PathForTesting("verify_uses_libraries.sh"), | 
|  | 330 | ConstructContext:    android.PathForTesting("construct_context.sh"), | 
|  | 331 | }, | 
|  | 332 | } | 
|  | 333 | } |