PackageManagerServiceCompilerMapping.java revision e131dac848cb4d0998e1dee2219382250c71d277
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", "inactive", "shared" 30 }; 31 32 static final int REASON_SHARED_INDEX = 6; 33 34 // Static block to ensure the strings array is of the right length. 35 static { 36 if (PackageManagerService.REASON_LAST + 1 != REASON_STRINGS.length) { 37 throw new IllegalStateException("REASON_STRINGS not correct"); 38 } 39 if (!"shared".equals(REASON_STRINGS[REASON_SHARED_INDEX])) { 40 throw new IllegalStateException("REASON_STRINGS not correct because of shared index"); 41 } 42 } 43 44 private static String getSystemPropertyName(int reason) { 45 if (reason < 0 || reason >= REASON_STRINGS.length) { 46 throw new IllegalArgumentException("reason " + reason + " invalid"); 47 } 48 49 return "pm.dexopt." + REASON_STRINGS[reason]; 50 } 51 52 // Load the property for the given reason and check for validity. This will throw an 53 // exception in case the reason or value are invalid. 54 private static String getAndCheckValidity(int reason) { 55 String sysPropName = getSystemPropertyName(reason); 56 String sysPropValue; 57 // TODO: This is a temporary hack to keep marlin booting on aosp/master while we 58 // figure out how to deal with these system properties that currently appear on 59 // vendor. 60 if ("pm.dexopt.inactive".equals(sysPropName)) { 61 sysPropValue = "verify"; 62 } else if ("pm.dexopt.shared".equals(sysPropName)) { 63 sysPropValue = "speed"; 64 } else { 65 sysPropValue = SystemProperties.get(sysPropName); 66 } 67 if (sysPropValue == null || sysPropValue.isEmpty() || 68 !DexFile.isValidCompilerFilter(sysPropValue)) { 69 throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid " 70 + "(reason " + REASON_STRINGS[reason] + ")"); 71 } else if (!isFilterAllowedForReason(reason, sysPropValue)) { 72 throw new IllegalStateException("Value \"" + sysPropValue +"\" not allowed " 73 + "(reason " + REASON_STRINGS[reason] + ")"); 74 } 75 76 return sysPropValue; 77 } 78 79 private static boolean isFilterAllowedForReason(int reason, String filter) { 80 return reason != REASON_SHARED_INDEX || !DexFile.isProfileGuidedCompilerFilter(filter); 81 } 82 83 // Check that the properties are set and valid. 84 // Note: this is done in a separate method so this class can be statically initialized. 85 static void checkProperties() { 86 // We're gonna check all properties and collect the exceptions, so we can give a general 87 // overview. Store the exceptions here. 88 RuntimeException toThrow = null; 89 90 for (int reason = 0; reason <= PackageManagerService.REASON_LAST; reason++) { 91 try { 92 // Check that the system property name is legal. 93 String sysPropName = getSystemPropertyName(reason); 94 if (sysPropName == null || sysPropName.isEmpty()) { 95 throw new IllegalStateException("Reason system property name \"" + 96 sysPropName +"\" for reason " + REASON_STRINGS[reason]); 97 } 98 99 // Check validity, ignore result. 100 getAndCheckValidity(reason); 101 } catch (Exception exc) { 102 if (toThrow == null) { 103 toThrow = new IllegalStateException("PMS compiler filter settings are bad."); 104 } 105 toThrow.addSuppressed(exc); 106 } 107 } 108 109 if (toThrow != null) { 110 throw toThrow; 111 } 112 } 113 114 public static String getCompilerFilterForReason(int reason) { 115 return getAndCheckValidity(reason); 116 } 117 118 /** 119 * Return the default compiler filter for compilation. 120 * 121 * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make 122 * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values. 123 */ 124 public static String getDefaultCompilerFilter() { 125 String value = SystemProperties.get("dalvik.vm.dex2oat-filter"); 126 if (value == null || value.isEmpty()) { 127 return "speed"; 128 } 129 130 if (!DexFile.isValidCompilerFilter(value) || 131 DexFile.isProfileGuidedCompilerFilter(value)) { 132 return "speed"; 133 } 134 135 return value; 136 } 137} 138