PackageManagerServiceCompilerMapping.java revision bdd30d86ef98456161069d11481b2ccd25a11b4e
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 */ 26class PackageManagerServiceCompilerMapping { 27 // Compilation reasons. 28 public static final int REASON_BOOT = 0; 29 public static final int REASON_INSTALL = 1; 30 public static final int REASON_BACKGROUND_DEXOPT = 2; 31 public static final int REASON_AB_OTA = 3; 32 public static final int REASON_NON_SYSTEM_LIBRARY = 4; 33 public static final int REASON_SHARED_APK = 5; 34 public static final int REASON_FORCED_DEXOPT = 6; 35 36 private static final int REASON_LAST = REASON_FORCED_DEXOPT; 37 38 // Names for compilation reasons. 39 static final String REASON_STRINGS[] = { 40 "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk", "forced-dexopt" 41 }; 42 43 // Static block to ensure the strings array is of the right length. 44 static { 45 if (REASON_LAST + 1 != REASON_STRINGS.length) { 46 throw new IllegalStateException("REASON_STRINGS not correct"); 47 } 48 } 49 50 private static String getSystemPropertyName(int reason) { 51 if (reason < 0 || reason >= REASON_STRINGS.length) { 52 throw new IllegalArgumentException("reason " + reason + " invalid"); 53 } 54 55 return "pm.dexopt." + REASON_STRINGS[reason]; 56 } 57 58 // Load the property for the given reason and check for validity. This will throw an 59 // exception in case the reason or value are invalid. 60 private static String getAndCheckValidity(int reason) { 61 String sysPropValue = SystemProperties.get(getSystemPropertyName(reason)); 62 if (sysPropValue == null || sysPropValue.isEmpty() || 63 !DexFile.isValidCompilerFilter(sysPropValue)) { 64 throw new IllegalStateException("Value \"" + sysPropValue +"\" not valid " 65 + "(reason " + REASON_STRINGS[reason] + ")"); 66 } 67 68 // Ensure that some reasons are not mapped to profile-guided filters. 69 switch (reason) { 70 case REASON_SHARED_APK: 71 case REASON_FORCED_DEXOPT: 72 if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) { 73 throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, " 74 + "but not allowed for " + REASON_STRINGS[reason]); 75 } 76 break; 77 } 78 79 return sysPropValue; 80 } 81 82 // Check that the properties are set and valid. 83 // Note: this is done in a separate method so this class can be statically initialized. 84 static void checkProperties() { 85 // We're gonna check all properties and collect the exceptions, so we can give a general 86 // overview. Store the exceptions here. 87 RuntimeException toThrow = null; 88 89 for (int reason = 0; reason <= REASON_LAST; reason++) { 90 try { 91 // Check that the system property name is legal. 92 String sysPropName = getSystemPropertyName(reason); 93 if (sysPropName == null || 94 sysPropName.isEmpty() || 95 sysPropName.length() > SystemProperties.PROP_NAME_MAX) { 96 throw new IllegalStateException("Reason system property name \"" + 97 sysPropName +"\" for reason " + REASON_STRINGS[reason]); 98 } 99 100 // Check validity, ignore result. 101 getAndCheckValidity(reason); 102 } catch (Exception exc) { 103 if (toThrow == null) { 104 toThrow = new IllegalStateException("PMS compiler filter settings are bad."); 105 } 106 toThrow.addSuppressed(exc); 107 } 108 } 109 110 if (toThrow != null) { 111 throw toThrow; 112 } 113 } 114 115 public static String getCompilerFilterForReason(int reason) { 116 return getAndCheckValidity(reason); 117 } 118 119 /** 120 * Return the compiler filter for "full" compilation. 121 * 122 * We derive that from the traditional "dalvik.vm.dex2oat-filter" property and just make 123 * sure this isn't profile-guided. Returns "speed" in case of invalid (or missing) values. 124 */ 125 public static String getFullCompilerFilter() { 126 String value = SystemProperties.get("dalvik.vm.dex2oat-filter"); 127 if (value == null || value.isEmpty()) { 128 return "speed"; 129 } 130 131 if (!DexFile.isValidCompilerFilter(value) || 132 DexFile.isProfileGuidedCompilerFilter(value)) { 133 return "speed"; 134 } 135 136 return value; 137 } 138 139} 140