1 /* 2 * Copyright (C) 2018 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 package com.android.internal.telephony.dataconnection; 18 19 import android.content.Context; 20 import android.os.PersistableBundle; 21 import android.telephony.Annotation.ApnType; 22 import android.telephony.CarrierConfigManager; 23 import android.telephony.data.ApnSetting; 24 25 import com.android.internal.telephony.Phone; 26 import com.android.telephony.Rlog; 27 28 import java.util.Arrays; 29 import java.util.HashSet; 30 31 /** 32 * This class represents a apn setting for create PDP link 33 */ 34 public class ApnSettingUtils { 35 36 static final String LOG_TAG = "ApnSetting"; 37 38 private static final boolean DBG = false; 39 40 /** 41 * Check if this APN type is metered. 42 * 43 * @param apnType the APN type 44 * @param phone the phone object 45 * @return {@code true} if the APN type is metered, {@code false} otherwise. 46 */ isMeteredApnType(@pnType int apnType, Phone phone)47 public static boolean isMeteredApnType(@ApnType int apnType, Phone phone) { 48 if (phone == null) { 49 return true; 50 } 51 52 boolean isRoaming = phone.getServiceState().getDataRoaming(); 53 int subId = phone.getSubId(); 54 55 String carrierConfig; 56 // First check if the device is roaming. If yes, use the roaming metered APN list. 57 // Otherwise use the normal metered APN list. 58 if (isRoaming) { 59 carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS; 60 } else { 61 carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS; 62 } 63 64 if (DBG) { 65 Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming); 66 } 67 68 CarrierConfigManager configManager = (CarrierConfigManager) 69 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 70 if (configManager == null) { 71 Rlog.e(LOG_TAG, "Carrier config service is not available"); 72 return true; 73 } 74 75 PersistableBundle b = configManager.getConfigForSubId(subId); 76 if (b == null) { 77 Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId); 78 return true; 79 } 80 81 String[] meteredApnTypes = b.getStringArray(carrierConfig); 82 if (meteredApnTypes == null) { 83 Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId); 84 return true; 85 } 86 87 HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes)); 88 if (DBG) { 89 Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are " 90 + Arrays.toString(meteredApnSet.toArray())); 91 } 92 93 if (meteredApnSet.contains(ApnSetting.getApnTypeString(apnType))) { 94 if (DBG) Rlog.d(LOG_TAG, ApnSetting.getApnTypeString(apnType) + " is metered."); 95 return true; 96 } else if (apnType == ApnSetting.TYPE_ALL) { 97 // Assuming no configuration error, if at least one APN type is 98 // metered, then this APN setting is metered. 99 if (meteredApnSet.size() > 0) { 100 if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered."); 101 return true; 102 } 103 } 104 105 if (DBG) Rlog.d(LOG_TAG, ApnSetting.getApnTypeString(apnType) + " is not metered."); 106 return false; 107 } 108 109 /** 110 * Check if this APN setting is metered. 111 * 112 * @param apn APN setting 113 * @param phone The phone object 114 * @return True if this APN setting is metered, otherwise false. 115 */ isMetered(ApnSetting apn, Phone phone)116 public static boolean isMetered(ApnSetting apn, Phone phone) { 117 if (phone == null || apn == null) { 118 return true; 119 } 120 121 for (int apnType : apn.getApnTypes()) { 122 // If one of the APN type is metered, then this APN setting is metered. 123 if (isMeteredApnType(apnType, phone)) { 124 return true; 125 } 126 } 127 return false; 128 } 129 } 130