• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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