ProcessExpressions.java revision e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10
197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar/* 297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * 497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * you may not use this file except in compliance with the License. 697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * You may obtain a copy of the License at 797d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * 897d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 997d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * 1097d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * Unless required by applicable law or agreed to in writing, software 1197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1297d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * See the License for the specific language governing permissions and 1497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar * limitations under the License. 1597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar */ 1697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.annotationprocessor; 18e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount 19a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport org.apache.commons.io.FileUtils; 201b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport org.apache.commons.io.IOUtils; 21b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyarimport org.apache.commons.lang3.StringUtils; 221b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingBuildInfo; 24fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.CompilerChef; 25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.SdkUtil; 26fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.store.ResourceBundle; 27fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.GenerationalClassUtil; 28fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L; 294df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyarimport android.databinding.tool.writer.BRWriter; 301b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 3197d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyarimport java.io.File; 32a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.io.FilenameFilter; 33e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport java.io.IOException; 34a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.io.InputStream; 35a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.io.Serializable; 36a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.HashMap; 37a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.List; 38a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.Map; 39b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyarimport java.util.Set; 40e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount 41a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport javax.annotation.processing.ProcessingEnvironment; 42e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mountimport javax.annotation.processing.RoundEnvironment; 438e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBContext; 448e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.JAXBException; 458e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.xml.bind.Unmarshaller; 46e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount 47a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarpublic class ProcessExpressions extends ProcessDataBinding.ProcessingStep { 484df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar public ProcessExpressions() { 4961630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 5061630faa88ee4817834d47294a0e17f19d8e1c51George Mount 51a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 52a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public boolean onHandleStep(RoundEnvironment roundEnvironment, 53a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) { 54a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar ResourceBundle resourceBundle; 55a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar SdkUtil.initialize(buildInfo.minSdk(), new File(buildInfo.sdkRoot())); 56a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar resourceBundle = new ResourceBundle(buildInfo.modulePackage()); 57a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar List<Intermediate> intermediateList = 58e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar GenerationalClassUtil.loadObjects( 59e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar GenerationalClassUtil.ExtensionFilter.LAYOUT); 60a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar IntermediateV1 mine = createIntermediateFromLayouts(buildInfo.layoutInfoDir()); 61a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (mine != null) { 62a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mine.removeOverridden(intermediateList); 63a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar intermediateList.add(mine); 64a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar saveIntermediate(processingEnvironment, buildInfo, mine); 65a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 66a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // generate them here so that bindable parser can read 67a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar try { 68a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar generateBinders(resourceBundle, buildInfo, intermediateList); 69a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } catch (Throwable t) { 70a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.e(t, "cannot generate view binders"); 71a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 72a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return true; 73a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 74a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 75a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private void saveIntermediate(ProcessingEnvironment processingEnvironment, 76a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar BindingBuildInfo buildInfo, IntermediateV1 intermediate) { 77a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar GenerationalClassUtil.writeIntermediateFile(processingEnvironment, 78e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar buildInfo.modulePackage(), buildInfo.modulePackage() + 79e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar GenerationalClassUtil.ExtensionFilter.LAYOUT.getExtension(), 80a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar intermediate); 81a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 82a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 83a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 84a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void onProcessingOver(RoundEnvironment roundEnvironment, 85a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) { 86a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 87a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 88a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private void generateBinders(ResourceBundle resourceBundle, BindingBuildInfo buildInfo, 89a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar List<Intermediate> intermediates) 90a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar throws Throwable { 91a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (Intermediate intermediate : intermediates) { 92a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar intermediate.appendTo(resourceBundle); 93a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 94b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar writeResourceBundle(resourceBundle, buildInfo.isLibrary(), buildInfo.minSdk(), 95b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar buildInfo.exportClassListTo()); 96a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 97a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 98a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private IntermediateV1 createIntermediateFromLayouts(String layoutInfoFolderPath) { 99a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final File layoutInfoFolder = new File(layoutInfoFolderPath); 100a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (!layoutInfoFolder.isDirectory()) { 101a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("layout info folder does not exist, skipping for %s", layoutInfoFolderPath); 102a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return null; 103a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 104a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar IntermediateV1 result = new IntermediateV1(); 105a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (File layoutFile : layoutInfoFolder.listFiles(new FilenameFilter() { 106a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 107a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public boolean accept(File dir, String name) { 108a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return name.endsWith(".xml"); 10900da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 110a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar })) { 111a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar try { 112a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar result.addEntry(layoutFile.getName(), FileUtils.readFileToString(layoutFile)); 113a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } catch (IOException e) { 114a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.e(e, "cannot load layout file information. Try a clean build"); 1151b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 116a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 117a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return result; 118a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 119a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 120e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount private void writeResourceBundle(ResourceBundle resourceBundle, boolean forLibraryModule, 1214df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar final int minSdk, String exportClassNamesTo) 122a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar throws JAXBException { 1234df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar final CompilerChef compilerChef = CompilerChef.createChef(resourceBundle, getWriter()); 124a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (compilerChef.hasAnythingToGenerate()) { 125dea555cf42dc3583604699c8c018d22681f56166George Mount compilerChef.writeViewBinderInterfaces(forLibraryModule); 126a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (!forLibraryModule) { 12796e1c821dd446d1ed78f8ae61131550588f60a24George Mount compilerChef.writeViewBinders(minSdk); 1281b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1291b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 130b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar if (forLibraryModule && exportClassNamesTo == null) { 131b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar L.e("When compiling a library module, build info must include exportClassListTo path"); 132b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar } 133b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar if (forLibraryModule) { 134b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar Set<String> classNames = compilerChef.getWrittenClassNames(); 135b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar String out = StringUtils.join(classNames, System.getProperty("line.separator")); 136b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar L.d("Writing list of classes to %s . \nList:%s", exportClassNamesTo, out); 137b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar try { 1384df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar //noinspection ConstantConditions 1394df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar FileUtils.write(new File(exportClassNamesTo), out); 140b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar } catch (IOException e) { 141b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar L.e(e, "Cannot create list of written classes"); 142b6887f1479c3ecec38a7989748ef33de1fbcd973Yigit Boyar } 1431bbaf7cdf7f9d93ae09365192abb2288cf0dfb41George Mount } 1444df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar mCallback.onChefReady(compilerChef, forLibraryModule, minSdk); 145a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 146e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount 147a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public static interface Intermediate extends Serializable { 148a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 149a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar Intermediate upgrade(); 150a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 151a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void appendTo(ResourceBundle resourceBundle) throws Throwable; 1528e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 1538e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 154a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public static class IntermediateV1 implements Intermediate { 155a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 156a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar transient Unmarshaller mUnmarshaller; 157a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 158a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // name to xml content map 159b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar Map<String, String> mLayoutInfoMap = new HashMap<String, String>(); 160a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 161a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 162a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public Intermediate upgrade() { 163a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return this; 164a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 165a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 166a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 167a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void appendTo(ResourceBundle resourceBundle) throws JAXBException { 168a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (mUnmarshaller == null) { 169a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar JAXBContext context = JAXBContext 170a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar .newInstance(ResourceBundle.LayoutFileBundle.class); 171a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mUnmarshaller = context.createUnmarshaller(); 1728e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 173a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (String content : mLayoutInfoMap.values()) { 174a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final InputStream is = IOUtils.toInputStream(content); 175a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar try { 176a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar final ResourceBundle.LayoutFileBundle bundle 177a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar = (ResourceBundle.LayoutFileBundle) mUnmarshaller.unmarshal(is); 1780390898cf7c4fcad255e8cfd6802f722b516cb2cGeorge Mount resourceBundle.addLayoutBundle(bundle); 179a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("loaded layout info file %s", bundle); 180a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } finally { 181a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar IOUtils.closeQuietly(is); 1821b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1831b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 184a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 1858e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 186a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void addEntry(String name, String contents) { 187a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mLayoutInfoMap.put(name, contents); 1881b9940e612fc73202837fbe9db2f9035f307b5d1George Mount } 1898e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount 190a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void removeOverridden(List<Intermediate> existing) { 191a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // this is the way we get rid of files that are copied from previous modules 192a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // it is important to do this before saving the intermediate file 193a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (Intermediate old : existing) { 194a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (old instanceof IntermediateV1) { 195a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar IntermediateV1 other = (IntermediateV1) old; 196a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (String key : other.mLayoutInfoMap.keySet()) { 197a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // TODO we should consider the original file as the key here 198a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // but aapt probably cannot provide that information 199a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (mLayoutInfoMap.remove(key) != null) { 200a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("removing %s from bundle because it came from another module", key); 201a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 202a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 203a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 204a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 20500da715547ee7d5d38a3b8576090ca427a94daa5George Mount } 206e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount } 207e6c6d3bf4fac3fa11c5780cfd3bc14cdb0caaea1George Mount} 208