PackageManagerServiceCompilerMapping.java revision 9cea1d28dd96b05cf3cb910e03ade9dfc5146745
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 17package com.android.server.pm; 18 19import android.os.SystemProperties; 20 21import dalvik.system.DexFile; 22 23/** 24 * Manage (retrieve) mappings from compilation reason to compilation filter. 25 */ 26public class PackageManagerServiceCompilerMapping { 27 // Names for compilation reasons. 28 static final String REASON_STRINGS[] = { 29 "first-boot", "boot", "install", "bg-dexopt", "ab-ota" 30 }; 31 32 // Static block to ensure the strings array is of the right length. 33 static { 34 if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) { 35 throw new IllegalStateException("REASON_STRINGS not correct"); 36 } 37 } 38 39 private static String getSystemPropertyName(int reason) { 40 if (reason < 0 || reason >= REASON_STRINGS.length) { 41 throw new IllegalArgumentException("reason " + reason + " invalid"); 42 } 43 44 return "pm.dexopt." + REASON_STRINGS[reason]; 45 } 46 47 // Load the property for the given reason and check for validity. This will throw an 48 // exception in case the reason or value are invalid. 49 private static String getAndCheckValidity(int reason) { 50 String sysPropValue = SystemProperties.get(getSystemPropertyName(reason)); 51 if (sysPropValue == null || sysPropValue.isEmpty() || 52 !DexFile.isValidCompilerFilter(sysPropValue)) { 53 throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid " 54 + "(reason " + REASON_STRINGS[reason] + ")"); 55 } 56 57 return sysPropValue; 58 } 59 60 // Check that the properties are set and valid. 61 // Note: this is done in a separate method so this class can be statically initialized. 62 static void checkProperties() { 63 // We're gonna check all properties and collect the exceptions, so we can give a general 64 // overview. Store the exceptions here. 65 RuntimeException toThrow = null; 66 67 for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) { 68 try { 69 // Check that the system property name is legal. 70 String sysPropName = getSystemPropertyName(reason); 71 if (sysPropName == null || sysPropName.isEmpty()) { 72 throw new IllegalStateException("Reason system property name \"" + 73 sysPropName +"\" for reason " + REASON_STRINGS[reason]); 74 } 75 76 // Check validity, ignore result. 77 getAndCheckValidity(reason); 78 } catch (Exception exc) { 79 if (toThrow == null) { 80 toThrow = new IllegalStateException("PMS compiler filter settings are bad."); 81 } 82 toThrow.addSuppressed(exc); 83 } 84 } 85 86 if (toThrow != null) { 87 throw toThrow; 88 } 89 } 90 91 public static String getCompilerFilterForReason(int reason) { 92 return getAndCheckValidity(reason); 93 } 94 95 /** 96 * Return the default compiler filter for compilation. 97 * 98 * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make 99 * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values. 100 */ 101 public static String getDefaultCompilerFilter() { 102 String value = SystemProperties.get("dalvik.vm.dex2oat-filter"); 103 if (value == null || value.isEmpty()) { 104 return "speed"; 105 } 106 107 if (!DexFile.isValidCompilerFilter(value) || 108 DexFile.isProfileGuidedCompilerFilter(value)) { 109 return "speed"; 110 } 111 112 return value; 113 } 114 115 /** 116 * Return the non-profile-guided filter corresponding to the given filter. 117 */ 118 public static String getNonProfileGuidedCompilerFilter(String filter) { 119 return DexFile.getNonProfileGuidedCompilerFilter(filter); 120 } 121} 122