1 /* 2 * Copyright 2020 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.google.android.iwlan; 18 19 import android.content.Context; 20 import android.net.ConnectivityManager; 21 import android.net.LinkAddress; 22 import android.net.LinkProperties; 23 import android.net.Network; 24 import android.os.PersistableBundle; 25 import android.telephony.CarrierConfigManager; 26 import android.telephony.SubscriptionInfo; 27 import android.telephony.SubscriptionManager; 28 import android.telephony.TelephonyManager; 29 import android.telephony.ims.ImsManager; 30 import android.telephony.ims.ImsMmTelManager; 31 32 import java.net.Inet4Address; 33 import java.net.Inet6Address; 34 import java.net.InetAddress; 35 import java.util.ArrayList; 36 import java.util.List; 37 38 public class IwlanHelper { 39 40 private static final String TAG = IwlanHelper.class.getSimpleName(); 41 getNai(Context context, int slotId)42 public static String getNai(Context context, int slotId) { 43 StringBuilder naiBuilder = new StringBuilder(); 44 TelephonyManager tm = context.getSystemService(TelephonyManager.class); 45 SubscriptionInfo subInfo = null; 46 tm = tm.createForSubscriptionId(getSubId(context, slotId)); 47 48 try { 49 subInfo = getSubInfo(context, slotId); 50 } catch (IllegalStateException e) { 51 return null; 52 } 53 54 String mnc = subInfo.getMncString(); 55 mnc = (mnc.length() == 2) ? '0' + mnc : mnc; 56 57 naiBuilder.append('0').append(tm.getSubscriberId()).append('@'); 58 59 return naiBuilder 60 .append("nai.epc.mnc") 61 .append(mnc) 62 .append(".mcc") 63 .append(subInfo.getMccString()) 64 .append(".3gppnetwork.org") 65 .toString(); 66 } 67 getSubId(Context context, int slotId)68 public static int getSubId(Context context, int slotId) { 69 int subid = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 70 71 try { 72 subid = getSubInfo(context, slotId).getSubscriptionId(); 73 } catch (IllegalStateException e) { 74 subid = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 75 } 76 return subid; 77 } 78 getCarrierId(Context context, int slotId)79 public static int getCarrierId(Context context, int slotId) { 80 TelephonyManager tm = context.getSystemService(TelephonyManager.class); 81 tm = tm.createForSubscriptionId(IwlanHelper.getSubId(context, slotId)); 82 return tm.getSimCarrierId(); 83 } 84 getSubInfo(Context context, int slotId)85 private static SubscriptionInfo getSubInfo(Context context, int slotId) 86 throws IllegalStateException { 87 SubscriptionManager sm = context.getSystemService(SubscriptionManager.class); 88 SubscriptionInfo info = sm.getActiveSubscriptionInfoForSimSlotIndex(slotId); 89 90 if (info == null) { 91 throw new IllegalStateException("Subscription info is null."); 92 } 93 94 return info; 95 } 96 getAddressesForNetwork(Network network, Context context)97 public static List<InetAddress> getAddressesForNetwork(Network network, Context context) { 98 ConnectivityManager connectivityManager = 99 context.getSystemService(ConnectivityManager.class); 100 List<InetAddress> gatewayList = new ArrayList<InetAddress>(); 101 if (network != null) { 102 LinkProperties linkProperties = connectivityManager.getLinkProperties(network); 103 if (linkProperties != null) { 104 for (LinkAddress laddr : linkProperties.getLinkAddresses()) { 105 InetAddress inetaddr = laddr.getAddress(); 106 // skip linklocal and loopback addresses 107 if (!inetaddr.isLoopbackAddress() && !inetaddr.isLinkLocalAddress()) { 108 gatewayList.add(inetaddr); 109 } 110 } 111 } 112 } 113 return gatewayList; 114 } 115 hasIpv6Address(List<InetAddress> localAddresses)116 public static boolean hasIpv6Address(List<InetAddress> localAddresses) { 117 for (InetAddress address : localAddresses) { 118 if (address instanceof Inet6Address) { 119 return true; 120 } 121 } 122 123 return false; 124 } 125 hasIpv4Address(List<InetAddress> localAddresses)126 public static boolean hasIpv4Address(List<InetAddress> localAddresses) { 127 for (InetAddress address : localAddresses) { 128 if (address instanceof Inet4Address) { 129 return true; 130 } 131 } 132 133 return false; 134 } 135 getIpv4Address(List<InetAddress> localAddresses)136 public static InetAddress getIpv4Address(List<InetAddress> localAddresses) { 137 for (InetAddress address : localAddresses) { 138 if (address instanceof Inet4Address) { 139 return address; 140 } 141 } 142 143 throw new IllegalStateException("Local address should not be null."); 144 } 145 getIpv6Address(List<InetAddress> localAddresses)146 public static InetAddress getIpv6Address(List<InetAddress> localAddresses) { 147 for (InetAddress address : localAddresses) { 148 if (address instanceof Inet6Address) { 149 return address; 150 } 151 } 152 153 throw new IllegalStateException("Local address should not be null."); 154 } 155 getConfig(String key, Context context, int slotId)156 public static <T> T getConfig(String key, Context context, int slotId) { 157 CarrierConfigManager carrierConfigManager = 158 context.getSystemService(CarrierConfigManager.class); 159 if (carrierConfigManager == null) { 160 throw new IllegalStateException("Carrier config manager is null."); 161 } 162 163 PersistableBundle bundle = 164 carrierConfigManager.getConfigForSubId(getSubId(context, slotId)); 165 166 if (bundle == null || bundle.get(key) == null) { 167 return getDefaultConfig(key); 168 } else { 169 return (T) bundle.get(key); 170 } 171 } 172 getDefaultConfig(String key)173 public static <T> T getDefaultConfig(String key) { 174 PersistableBundle bundle = CarrierConfigManager.getDefaultConfig(); 175 if (bundle == null) { 176 throw new IllegalStateException("Default config is null for: " + key); 177 } 178 return (T) bundle.get(key); 179 } 180 isDefaultDataSlot(Context context, int slotId)181 public static boolean isDefaultDataSlot(Context context, int slotId) { 182 SubscriptionManager sm = context.getSystemService(SubscriptionManager.class); 183 int ddsSlotId = sm.getSlotIndex(sm.getDefaultDataSubscriptionId()); 184 if (ddsSlotId != sm.INVALID_SIM_SLOT_INDEX) { 185 if (ddsSlotId == slotId) { 186 return true; 187 } 188 } 189 return false; 190 } 191 isCrossSimCallingEnabled(Context context, int slotId)192 public static boolean isCrossSimCallingEnabled(Context context, int slotId) { 193 boolean isCstEnabled = false; 194 int subid = getSubId(context, slotId); 195 196 if (subid == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 197 // Fail to query subscription id, just return false. 198 return false; 199 } 200 201 ImsManager imsManager = context.getSystemService(ImsManager.class); 202 if (imsManager != null) { 203 ImsMmTelManager imsMmTelManager = imsManager.getImsMmTelManager(subid); 204 if (imsMmTelManager != null) { 205 try { 206 isCstEnabled = imsMmTelManager.isCrossSimCallingEnabled(); 207 } catch (Exception e) { 208 // Fail to query Cross-SIM calling setting, just return false to avoid an 209 // exception. 210 } 211 } 212 } 213 return isCstEnabled; 214 } 215 } 216