19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.tools.layoutlib.create; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static org.junit.Assert.assertArrayEquals; 224f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Guptaimport static org.junit.Assert.assertFalse; 231cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport static org.junit.Assert.assertTrue; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.junit.After; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.junit.Before; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.junit.Test; 281cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport org.objectweb.asm.ClassReader; 291cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport org.objectweb.asm.ClassVisitor; 301cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport org.objectweb.asm.FieldVisitor; 311cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport org.objectweb.asm.MethodVisitor; 321cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport org.objectweb.asm.Opcodes; 331cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport org.objectweb.asm.Type; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 3758037a4404e639d28695a0f1c17053b53b96b970Deepanshu Guptaimport java.io.InputStream; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.URL; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 404f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Guptaimport java.util.Collections; 411cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport java.util.Enumeration; 421cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport java.util.HashSet; 431cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport java.util.Map; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 451cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport java.util.TreeMap; 461cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport java.util.zip.ZipEntry; 471cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Guptaimport java.util.zip.ZipFile; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unit tests for some methods of {@link AsmGenerator}. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AsmGeneratorTest { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MockLog mLog; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<String> mOsJarPath; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mOsDestJar; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private File mTempFile; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 591cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta // ASM internal name for the the class in java package that should be refactored. 601cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta private static final String JAVA_CLASS_NAME = "java/lang/JavaClass"; 611cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Before 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setUp() throws Exception { 64bc101806249eb883f89c4a770a8c27f9ac315837Raphael mLog = new MockLog(); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar"); 66bc101806249eb883f89c4a770a8c27f9ac315837Raphael 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOsJarPath = new ArrayList<String>(); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOsJarPath.add(url.getFile()); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 701cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta mTempFile = File.createTempFile("mock", ".jar"); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOsDestJar = mTempFile.getAbsolutePath(); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempFile.deleteOnExit(); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @After 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void tearDown() throws Exception { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTempFile != null) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempFile.delete(); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTempFile = null; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Test 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void testClassRenaming() throws IOException, LogAbortException { 85bc101806249eb883f89c4a770a8c27f9ac315837Raphael 86bc101806249eb883f89c4a770a8c27f9ac315837Raphael ICreateInfo ci = new ICreateInfo() { 8746d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 88bc101806249eb883f89c4a770a8c27f9ac315837Raphael public Class<?>[] getInjectedClasses() { 89bc101806249eb883f89c4a770a8c27f9ac315837Raphael // classes to inject in the final JAR 90bc101806249eb883f89c4a770a8c27f9ac315837Raphael return new Class<?>[0]; 91bc101806249eb883f89c4a770a8c27f9ac315837Raphael } 92bc101806249eb883f89c4a770a8c27f9ac315837Raphael 9346d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 94bc101806249eb883f89c4a770a8c27f9ac315837Raphael public String[] getDelegateMethods() { 95bc101806249eb883f89c4a770a8c27f9ac315837Raphael return new String[0]; 96bc101806249eb883f89c4a770a8c27f9ac315837Raphael } 97bc101806249eb883f89c4a770a8c27f9ac315837Raphael 9846d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 99bc101806249eb883f89c4a770a8c27f9ac315837Raphael public String[] getDelegateClassNatives() { 100bc101806249eb883f89c4a770a8c27f9ac315837Raphael return new String[0]; 101bc101806249eb883f89c4a770a8c27f9ac315837Raphael } 102bc101806249eb883f89c4a770a8c27f9ac315837Raphael 10346d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 104bc101806249eb883f89c4a770a8c27f9ac315837Raphael public String[] getOverriddenMethods() { 105bc101806249eb883f89c4a770a8c27f9ac315837Raphael // methods to force override 106bc101806249eb883f89c4a770a8c27f9ac315837Raphael return new String[0]; 107bc101806249eb883f89c4a770a8c27f9ac315837Raphael } 108bc101806249eb883f89c4a770a8c27f9ac315837Raphael 10946d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 110bc101806249eb883f89c4a770a8c27f9ac315837Raphael public String[] getRenamedClasses() { 111bc101806249eb883f89c4a770a8c27f9ac315837Raphael // classes to rename (so that we can replace them) 112bc101806249eb883f89c4a770a8c27f9ac315837Raphael return new String[] { 113bc101806249eb883f89c4a770a8c27f9ac315837Raphael "mock_android.view.View", "mock_android.view._Original_View", 114bc101806249eb883f89c4a770a8c27f9ac315837Raphael "not.an.actual.ClassName", "anoter.fake.NewClassName", 115bc101806249eb883f89c4a770a8c27f9ac315837Raphael }; 116bc101806249eb883f89c4a770a8c27f9ac315837Raphael } 117bc101806249eb883f89c4a770a8c27f9ac315837Raphael 11846d43ccfd8cef75b4315828073c094cf1efb05ffXavier Ducrohet @Override 1191cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getJavaPkgClasses() { 1201cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[0]; 1211cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1221cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1231cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1244f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public Set<String> getExcludedClasses() { 1254f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return null; 1264f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 1274f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 1284f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 129bc101806249eb883f89c4a770a8c27f9ac315837Raphael public String[] getDeleteReturns() { 130bc101806249eb883f89c4a770a8c27f9ac315837Raphael // methods deleted from their return type. 131bc101806249eb883f89c4a770a8c27f9ac315837Raphael return new String[0]; 132bc101806249eb883f89c4a770a8c27f9ac315837Raphael } 133bc101806249eb883f89c4a770a8c27f9ac315837Raphael }; 134bc101806249eb883f89c4a770a8c27f9ac315837Raphael 135bc101806249eb883f89c4a770a8c27f9ac315837Raphael AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen, 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null, // derived from 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String[] { // include classes 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "**" 1411cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta }, 14258037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta new HashSet<String>(0) /* excluded classes */, 14358037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta new String[]{} /* include files */); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project aa.analyze(); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project agen.generate(); 146bc101806249eb883f89c4a770a8c27f9ac315837Raphael 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Set<String> notRenamed = agen.getClassesNotRenamed(); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertArrayEquals(new String[] { "not/an/actual/ClassName" }, notRenamed.toArray()); 1491cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1501cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1511cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1521cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Test 1531cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public void testClassRefactoring() throws IOException, LogAbortException { 1541cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta ICreateInfo ci = new ICreateInfo() { 1551cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1561cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public Class<?>[] getInjectedClasses() { 1571cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta // classes to inject in the final JAR 1581cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new Class<?>[] { 1591cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta com.android.tools.layoutlib.create.dataclass.JavaClass.class 1601cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta }; 1611cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1621cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1631cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1641cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getDelegateMethods() { 1651cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[0]; 1661cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1671cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1681cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1691cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getDelegateClassNatives() { 1701cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[0]; 1711cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1721cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1731cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1741cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getOverriddenMethods() { 1751cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta // methods to force override 1761cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[0]; 1771cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1781cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1791cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1801cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getRenamedClasses() { 1811cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta // classes to rename (so that we can replace them) 1821cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[0]; 1831cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1841cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1851cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1861cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getJavaPkgClasses() { 1871cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta // classes to refactor (so that we can replace them) 1881cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[] { 1891cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta "java.lang.JavaClass", "com.android.tools.layoutlib.create.dataclass.JavaClass", 1901cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta }; 1911cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 1921cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 1931cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 1944f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public Set<String> getExcludedClasses() { 1954f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return Collections.singleton("java.lang.JavaClass"); 1964f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 1974f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 1984f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 1991cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public String[] getDeleteReturns() { 2001cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta // methods deleted from their return type. 2011cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new String[0]; 2021cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 2031cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta }; 2041cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 2051cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci); 2061cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 2071cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen, 2081cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta null, // derived from 2091cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta new String[] { // include classes 2101cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta "**" 2111cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta }, 21258037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta new HashSet<String>(1), 21358037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta new String[] { /* include files */ 21458037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta "mock_android/data/data*" 21558037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta }); 2161cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta aa.analyze(); 2171cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta agen.generate(); 21858037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta Map<String, ClassReader> output = new TreeMap<String, ClassReader>(); 21958037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); 22058037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta parseZip(mOsDestJar, output, filesFound); 2211cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta boolean injectedClassFound = false; 2221cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta for (ClassReader cr: output.values()) { 2231cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta TestClassVisitor cv = new TestClassVisitor(); 2241cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta cr.accept(cv, 0); 2251cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta injectedClassFound |= cv.mInjectedClassFound; 2261cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 2271cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(injectedClassFound); 22858037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta assertArrayEquals(new String[] {"mock_android/data/dataFile"}, 22958037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta filesFound.keySet().toArray()); 2301cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 2311cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 2324f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Test 2334f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public void testClassExclusion() throws IOException, LogAbortException { 2344f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta ICreateInfo ci = new ICreateInfo() { 2354f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2364f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public Class<?>[] getInjectedClasses() { 2374f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new Class<?>[0]; 2384f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2394f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2404f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2414f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public String[] getDelegateMethods() { 2424f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new String[0]; 2434f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2444f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2454f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2464f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public String[] getDelegateClassNatives() { 2474f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new String[0]; 2484f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2494f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2504f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2514f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public String[] getOverriddenMethods() { 2524f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta // methods to force override 2534f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new String[0]; 2544f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2554f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2564f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2574f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public String[] getRenamedClasses() { 2584f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta // classes to rename (so that we can replace them) 2594f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new String[0]; 2604f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2614f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2624f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2634f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public String[] getJavaPkgClasses() { 2644f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta // classes to refactor (so that we can replace them) 2654f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new String[0]; 2664f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2674f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2684f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2694f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public Set<String> getExcludedClasses() { 2704f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta Set<String> set = new HashSet<String>(2); 2714f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta set.add("mock_android.dummy.InnerTest"); 2724f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta set.add("java.lang.JavaClass"); 2734f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return set; 2744f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2754f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2764f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta @Override 2774f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta public String[] getDeleteReturns() { 2784f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta // methods deleted from their return type. 2794f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta return new String[0]; 2804f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 2814f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta }; 2824f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 2834f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci); 2844f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta Set<String> excludedClasses = ci.getExcludedClasses(); 2854f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen, 2864f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta null, // derived from 2874f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta new String[] { // include classes 2884f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta "**" 2894f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta }, 2904f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta excludedClasses, 2914f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta new String[] { /* include files */ 2924f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta "mock_android/data/data*" 2934f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta }); 2944f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta aa.analyze(); 2954f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta agen.generate(); 2964f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta Map<String, ClassReader> output = new TreeMap<String, ClassReader>(); 2974f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta Map<String, InputStream> filesFound = new TreeMap<String, InputStream>(); 2984f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta parseZip(mOsDestJar, output, filesFound); 2994f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta for (String s : output.keySet()) { 3004f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta assertFalse(excludedClasses.contains(s)); 3014f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 3024f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta assertArrayEquals(new String[] {"mock_android/data/dataFile"}, 3034f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta filesFound.keySet().toArray()); 3044f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta } 3054f133894a6e98d8d30557ea42cec92cfb21fa5c9Deepanshu Gupta 30658037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta private void parseZip(String jarPath, 30758037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta Map<String, ClassReader> classes, 30858037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta Map<String, InputStream> filesFound) throws IOException { 3091cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3101cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta ZipFile zip = new ZipFile(jarPath); 3111cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta Enumeration<? extends ZipEntry> entries = zip.entries(); 3121cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta ZipEntry entry; 3131cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta while (entries.hasMoreElements()) { 3141cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta entry = entries.nextElement(); 3151cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (entry.getName().endsWith(".class")) { 3161cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta ClassReader cr = new ClassReader(zip.getInputStream(entry)); 3171cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta String className = classReaderToClassName(cr); 3181cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta classes.put(className, cr); 31958037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta } else { 32058037a4404e639d28695a0f1c17053b53b96b970Deepanshu Gupta filesFound.put(entry.getName(), zip.getInputStream(entry)); 3211cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3221cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3231cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3241cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3251cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3261cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta private String classReaderToClassName(ClassReader classReader) { 3271cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (classReader == null) { 3281cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return null; 3291cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } else { 3301cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return classReader.getClassName().replace('/', '.'); 3311cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3321cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3331cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3341cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta private class TestClassVisitor extends ClassVisitor { 3351cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3361cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta boolean mInjectedClassFound = false; 3371cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3381cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta TestClassVisitor() { 3391cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta super(Opcodes.ASM4); 3401cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3411cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3421cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3431cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public void visit(int version, int access, String name, String signature, 3441cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta String superName, String[] interfaces) { 3451cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(!getBase(name).equals(JAVA_CLASS_NAME)); 3461cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (name.equals("com/android/tools/layoutlib/create/dataclass/JavaClass")) { 3471cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta mInjectedClassFound = true; 3481cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3491cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta super.visit(version, access, name, signature, superName, interfaces); 3501cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3511cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3521cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3531cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public FieldVisitor visitField(int access, String name, String desc, 3541cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta String signature, Object value) { 3551cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(testType(Type.getType(desc))); 3561cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return super.visitField(access, name, desc, signature, value); 3571cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3581cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3591cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @SuppressWarnings("hiding") 3601cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3611cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public MethodVisitor visitMethod(int access, String name, String desc, 3621cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta String signature, String[] exceptions) { 3631cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 3641cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return new MethodVisitor(Opcodes.ASM4, mv) { 3651cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3661cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3671cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public void visitFieldInsn(int opcode, String owner, String name, 3681cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta String desc) { 3691cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME)); 3701cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(testType(Type.getType(desc))); 3711cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta super.visitFieldInsn(opcode, owner, name, desc); 3721cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3731cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3741cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3751cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public void visitLdcInsn(Object cst) { 3761cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (cst instanceof Type) { 3771cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(testType((Type)cst)); 3781cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3791cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta super.visitLdcInsn(cst); 3801cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3811cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3821cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3831cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public void visitTypeInsn(int opcode, String type) { 3841cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(!getBase(type).equals(JAVA_CLASS_NAME)); 3851cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta super.visitTypeInsn(opcode, type); 3861cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3871cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3881cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta @Override 3891cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta public void visitMethodInsn(int opcode, String owner, String name, 3901cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta String desc) { 3911cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME)); 3921cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(testType(Type.getType(desc))); 3931cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta super.visitMethodInsn(opcode, owner, name, desc); 3941cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3951cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3961cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta }; 3971cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 3981cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 3991cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta private boolean testType(Type type) { 4001cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta int sort = type.getSort(); 4011cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (sort == Type.OBJECT) { 4021cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(!getBase(type.getInternalName()).equals(JAVA_CLASS_NAME)); 4031cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } else if (sort == Type.ARRAY) { 4041cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta assertTrue(!getBase(type.getElementType().getInternalName()) 4051cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta .equals(JAVA_CLASS_NAME)); 4061cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } else if (sort == Type.METHOD) { 4071cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta boolean r = true; 4081cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta for (Type t : type.getArgumentTypes()) { 4091cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta r &= testType(t); 4101cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 4111cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return r & testType(type.getReturnType()); 4121cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 4131cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return true; 4141cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 4151cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta 4161cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta private String getBase(String className) { 4171cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (className == null) { 4181cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return null; 4191cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 4201cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta int pos = className.indexOf('$'); 4211cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta if (pos > 0) { 4221cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return className.substring(0, pos); 4231cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 4241cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta return className; 4251cf5df38f4bdafa1beb2674ca548ad6d9650766bDeepanshu Gupta } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 428