18c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt/* 28c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * Copyright (C) 2016 The Android Open Source Project 38c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * 48c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 58c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * you may not use this file except in compliance with the License. 68c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * You may obtain a copy of the License at 78c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * 88c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 98c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * 108c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * Unless required by applicable law or agreed to in writing, software 118c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 128c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * See the License for the specific language governing permissions and 148c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * limitations under the License. 158c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt */ 168c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltpackage com.android.internal.telephony; 178c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 188c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.content.BroadcastReceiver; 198c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.content.Context; 208c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.content.Intent; 218c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.content.IntentFilter; 228c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.os.PersistableBundle; 238c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.os.UserHandle; 248c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.telephony.CarrierConfigManager; 252cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwaltimport android.telephony.ServiceState; 268c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.telephony.Rlog; 278c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.util.SparseArray; 288c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.util.SparseIntArray; 298c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 308c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport java.util.ArrayList; 318c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 328c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt/** 338c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * This class loads configuration from CarrierConfig and uses it to determine 348c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * what RATs are within a ratcheting family. For example all the HSPA/HSDPA/HSUPA RATs. 358c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * Then, until reset the class will only ratchet upwards within the family (order 368c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * determined by the CarrierConfig data). The ServiceStateTracker will reset this 378c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * on cell-change. 388c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt */ 398c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltpublic class RatRatcheter { 408c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt private final static String LOG_TAG = "RilRatcheter"; 418c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 428c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt /** 438c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * This is a map of RAT types -> RAT families for rapid lookup. 448c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * The RAT families are defined by RAT type -> RAT Rank SparseIntArrays, so 458c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * we can compare the priorities of two RAT types by comparing the values 468c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * stored in the SparseIntArrays, higher values are higher priority. 478c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt */ 488c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt private final SparseArray<SparseIntArray> mRatFamilyMap = new SparseArray<>(); 498c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 508c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt private final Phone mPhone; 518c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 528c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt /** Constructor */ 538c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt public RatRatcheter(Phone phone) { 548c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt mPhone = phone; 558c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 568c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt IntentFilter intentFilter = new IntentFilter(); 578c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 588c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt phone.getContext().registerReceiverAsUser(mConfigChangedReceiver, UserHandle.ALL, 598c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt intentFilter, null, null); 608c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt resetRatFamilyMap(); 618c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 628c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 638c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt public int ratchetRat(int oldRat, int newRat) { 648c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt synchronized (mRatFamilyMap) { 658c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt final SparseIntArray oldFamily = mRatFamilyMap.get(oldRat); 668c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (oldFamily == null) return newRat; 678c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 688c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt final SparseIntArray newFamily = mRatFamilyMap.get(newRat); 698c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (newFamily != oldFamily) return newRat; 708c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 718c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt // now go with the higher of the two 728c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt final int oldRatRank = newFamily.get(oldRat, -1); 738c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt final int newRatRank = newFamily.get(newRat, -1); 748c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt return (oldRatRank > newRatRank ? oldRat : newRat); 758c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 768c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 778c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 782cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt public void ratchetRat(ServiceState oldSS, ServiceState newSS) { 792cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt int newVoiceRat = ratchetRat(oldSS.getRilVoiceRadioTechnology(), 802cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt newSS.getRilVoiceRadioTechnology()); 812cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt int newDataRat = ratchetRat(oldSS.getRilDataRadioTechnology(), 822cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt newSS.getRilDataRadioTechnology()); 832cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt boolean newUsingCA = oldSS.isUsingCarrierAggregation() || 842cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt newSS.isUsingCarrierAggregation(); 852cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt 862cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt newSS.setRilVoiceRadioTechnology(newVoiceRat); 872cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt newSS.setRilDataRadioTechnology(newDataRat); 882cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt newSS.setIsUsingCarrierAggregation(newUsingCA); 892cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt } 902cd7606f4d72cb7340c164aebb1835cd87f4996cRobert Greenwalt 918c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt private BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() { 928c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt @Override 938c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt public void onReceive(Context context, Intent intent) { 948c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt final String action = intent.getAction(); 958c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) { 968c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt resetRatFamilyMap(); 978c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 988c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 998c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt }; 1008c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 1018c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt private void resetRatFamilyMap() { 1028c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt synchronized(mRatFamilyMap) { 1038c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt mRatFamilyMap.clear(); 1048c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 1058c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt final CarrierConfigManager configManager = (CarrierConfigManager) 1068c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 1078c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (configManager == null) return; 1088c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt PersistableBundle b = configManager.getConfig(); 1098c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (b == null) return; 1108c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt 1118c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt // Reads an array of strings, eg: 1128c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt // ["GPRS, EDGE", "EVDO, EVDO_A, EVDO_B", "HSPA, HSDPA, HSUPA, HSPAP"] 1138c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt // Each string defines a family and the order of rats within the string express 1148c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt // the priority of the RAT within the family (ie, we'd move up to later-listed RATs, but 1158c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt // not down). 1168c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt String[] ratFamilies = b.getStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES); 1178c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (ratFamilies == null) return; 1188c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt for (String ratFamily : ratFamilies) { 1198c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt String[] rats = ratFamily.split(","); 1208c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (rats.length < 2) continue; 1218c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt SparseIntArray currentFamily = new SparseIntArray(rats.length); 1228c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt int pos = 0; 1238c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt for (String ratString : rats) { 1248c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt int ratInt; 1258c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt try { 1268c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt ratInt = Integer.parseInt(ratString.trim()); 1278c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } catch (NumberFormatException e) { 1288c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt Rlog.e(LOG_TAG, "NumberFormatException on " + ratString); 1298c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt break; 1308c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 1318c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt if (mRatFamilyMap.get(ratInt) != null) { 1328c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt Rlog.e(LOG_TAG, "RAT listed twice: " + ratString); 1338c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt break; 1348c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 1358c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt currentFamily.put(ratInt, pos++); 1368c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt mRatFamilyMap.put(ratInt, currentFamily); 1378c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 1388c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 1398c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 1408c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt } 1418c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt} 142