1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.io.File; 18 import java.io.IOException; 19 import java.lang.reflect.Method; 20 21 public class Main { 22 main(String[] args)23 public static void main(String[] args) throws Exception { 24 System.loadLibrary(args[0]); 25 26 File file = null; 27 try { 28 file = createTempFile(); 29 // String codePath = getDexBaseLocation(); 30 String codePath = System.getenv("DEX_LOCATION") + "/595-profile-saving.jar"; 31 VMRuntime.registerAppInfo("test.app", 32 file.getPath(), 33 file.getPath(), 34 new String[] {codePath}, 35 VMRuntime.CODE_PATH_TYPE_PRIMARY_APK); 36 37 // Test that the profile saves an app method with a profiling info. 38 Method appMethod = Main.class.getDeclaredMethod("testAddMethodToProfile", 39 File.class, Method.class); 40 testAddMethodToProfile(file, appMethod); 41 42 // Test that the profile saves a boot class path method with a profiling info. 43 Method bootMethod = File.class.getDeclaredMethod("delete"); 44 if (bootMethod.getDeclaringClass().getClassLoader() != Object.class.getClassLoader()) { 45 System.out.println("Class loader does not match boot class"); 46 } 47 testAddMethodToProfile(file, bootMethod); 48 49 System.out.println("IsForBootImage: " + isForBootImage(file.getPath())); 50 } finally { 51 if (file != null) { 52 file.delete(); 53 } 54 } 55 } 56 testAddMethodToProfile(File file, Method m)57 static void testAddMethodToProfile(File file, Method m) { 58 // Make sure we have a profile info for this method without the need to loop. 59 ensureProfilingInfo(m); 60 // Make sure the profile gets saved. 61 ensureProfileProcessing(); 62 // Verify that the profile was saved and contains the method. 63 if (!presentInProfile(file.getPath(), m)) { 64 throw new RuntimeException("Method with index " + m + " not in the profile"); 65 } 66 } 67 68 // Ensure a method has a profiling info. ensureProfilingInfo(Method method)69 public static native void ensureProfilingInfo(Method method); 70 // Ensures the profile saver does its usual processing. ensureProfileProcessing()71 public static native void ensureProfileProcessing(); 72 // Checks if the profiles saver knows about the method. presentInProfile(String profile, Method method)73 public static native boolean presentInProfile(String profile, Method method); 74 // Returns true if the profile is for the boot image. isForBootImage(String profile)75 public static native boolean isForBootImage(String profile); 76 77 private static final String TEMP_FILE_NAME_PREFIX = "temp"; 78 private static final String TEMP_FILE_NAME_SUFFIX = "-file"; 79 getProfileInfoDump( String filename)80 static native String getProfileInfoDump( 81 String filename); 82 createTempFile()83 private static File createTempFile() throws Exception { 84 try { 85 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 86 } catch (IOException e) { 87 System.setProperty("java.io.tmpdir", "/data/local/tmp"); 88 try { 89 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 90 } catch (IOException e2) { 91 System.setProperty("java.io.tmpdir", "/sdcard"); 92 return File.createTempFile(TEMP_FILE_NAME_PREFIX, TEMP_FILE_NAME_SUFFIX); 93 } 94 } 95 } 96 97 private static class VMRuntime { 98 public static final int CODE_PATH_TYPE_PRIMARY_APK = 1; 99 private static final Method registerAppInfoMethod; 100 101 static { 102 try { 103 Class<? extends Object> c = Class.forName("dalvik.system.VMRuntime"); 104 registerAppInfoMethod = c.getDeclaredMethod("registerAppInfo", 105 String.class, String.class, String.class, String[].class, int.class); 106 } catch (Exception e) { 107 throw new RuntimeException(e); 108 } 109 } 110 registerAppInfo( String packageName, String curProfile, String refProfile, String[] codePaths, int codePathsType)111 public static void registerAppInfo( 112 String packageName, 113 String curProfile, 114 String refProfile, 115 String[] codePaths, 116 int codePathsType) throws Exception { 117 registerAppInfoMethod.invoke( 118 null, 119 packageName, 120 curProfile, 121 refProfile, 122 codePaths, 123 codePathsType); 124 } 125 } 126 } 127