RatRatcheter.java revision 8c751b4ec57a6f2a7702d9ee003b0ec721c2ebac
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;
258c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.telephony.Rlog;
268c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.util.SparseArray;
278c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport android.util.SparseIntArray;
288c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
298c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltimport java.util.ArrayList;
308c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
318c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt/**
328c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * This class loads configuration from CarrierConfig and uses it to determine
338c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * what RATs are within a ratcheting family.  For example all the HSPA/HSDPA/HSUPA RATs.
348c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * Then, until reset the class will only ratchet upwards within the family (order
358c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * determined by the CarrierConfig data).  The ServiceStateTracker will reset this
368c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt * on cell-change.
378c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt */
388c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwaltpublic class RatRatcheter {
398c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    private final static String LOG_TAG = "RilRatcheter";
408c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
418c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    /**
428c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt     * This is a map of RAT types -> RAT families for rapid lookup.
438c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt     * The RAT families are defined by RAT type -> RAT Rank SparseIntArrays, so
448c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt     * we can compare the priorities of two RAT types by comparing the values
458c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt     * stored in the SparseIntArrays, higher values are higher priority.
468c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt     */
478c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    private final SparseArray<SparseIntArray> mRatFamilyMap = new SparseArray<>();
488c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
498c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    private final Phone mPhone;
508c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
518c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    /** Constructor */
528c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    public RatRatcheter(Phone phone) {
538c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        mPhone = phone;
548c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
558c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        IntentFilter intentFilter = new IntentFilter();
568c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
578c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        phone.getContext().registerReceiverAsUser(mConfigChangedReceiver, UserHandle.ALL,
588c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                intentFilter, null, null);
598c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        resetRatFamilyMap();
608c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    }
618c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
628c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    public int ratchetRat(int oldRat, int newRat) {
638c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        synchronized (mRatFamilyMap) {
648c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            final SparseIntArray oldFamily = mRatFamilyMap.get(oldRat);
658c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            if (oldFamily == null) return newRat;
668c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
678c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            final SparseIntArray newFamily = mRatFamilyMap.get(newRat);
688c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            if (newFamily != oldFamily) return newRat;
698c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
708c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            // now go with the higher of the two
718c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            final int oldRatRank = newFamily.get(oldRat, -1);
728c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            final int newRatRank = newFamily.get(newRat, -1);
738c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            return (oldRatRank > newRatRank ? oldRat : newRat);
748c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        }
758c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    }
768c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
778c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    private BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() {
788c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        @Override
798c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        public void onReceive(Context context, Intent intent) {
808c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            final String action = intent.getAction();
818c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
828c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                resetRatFamilyMap();
838c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            }
848c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        }
858c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    };
868c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
878c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    private void resetRatFamilyMap() {
888c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        synchronized(mRatFamilyMap) {
898c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            mRatFamilyMap.clear();
908c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
918c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            final CarrierConfigManager configManager = (CarrierConfigManager)
928c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
938c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            if (configManager == null) return;
948c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            PersistableBundle b = configManager.getConfig();
958c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            if (b == null) return;
968c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt
978c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            // Reads an array of strings, eg:
988c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            // ["GPRS, EDGE", "EVDO, EVDO_A, EVDO_B", "HSPA, HSDPA, HSUPA, HSPAP"]
998c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            // Each string defines a family and the order of rats within the string express
1008c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            // the priority of the RAT within the family (ie, we'd move up to later-listed RATs, but
1018c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            // not down).
1028c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            String[] ratFamilies = b.getStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES);
1038c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            if (ratFamilies == null) return;
1048c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            for (String ratFamily : ratFamilies) {
1058c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                String[] rats = ratFamily.split(",");
1068c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                if (rats.length < 2) continue;
1078c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                SparseIntArray currentFamily = new SparseIntArray(rats.length);
1088c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                int pos = 0;
1098c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                for (String ratString : rats) {
1108c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    int ratInt;
1118c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    try {
1128c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                        ratInt = Integer.parseInt(ratString.trim());
1138c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    } catch (NumberFormatException e) {
1148c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                        Rlog.e(LOG_TAG, "NumberFormatException on " + ratString);
1158c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                        break;
1168c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    }
1178c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    if (mRatFamilyMap.get(ratInt) != null) {
1188c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                        Rlog.e(LOG_TAG, "RAT listed twice: " + ratString);
1198c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                        break;
1208c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    }
1218c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    currentFamily.put(ratInt, pos++);
1228c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                    mRatFamilyMap.put(ratInt, currentFamily);
1238c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt                }
1248c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt            }
1258c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt        }
1268c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt    }
1278c751b4ec57a6f2a7702d9ee003b0ec721c2ebacRobert Greenwalt}
128