1 /* 2 * Copyright (C) 2021 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.telephony.qns; 18 19 import android.telephony.AccessNetworkConstants.AccessNetworkType; 20 import android.telephony.SignalThresholdInfo; 21 import android.util.Log; 22 23 import java.util.ArrayList; 24 import java.util.List; 25 import java.util.concurrent.atomic.AtomicInteger; 26 27 class ThresholdGroup { 28 private static final AtomicInteger sGid = new AtomicInteger(); 29 30 private final List<Threshold> mThresholds; 31 private final String mTag; 32 ThresholdGroup(List<Threshold> ths)33 ThresholdGroup(List<Threshold> ths) { 34 int groupId = sGid.getAndIncrement(); 35 mThresholds = alignGroupId(groupId, ths); 36 mTag = ThresholdGroup.class.getSimpleName() + groupId; 37 } 38 alignGroupId(int groupId, List<Threshold> ths)39 private List<Threshold> alignGroupId(int groupId, List<Threshold> ths) { 40 if (ths == null) { 41 return new ArrayList<>(); 42 } 43 ArrayList<Threshold> newList = new ArrayList<>(ths); 44 for (Threshold th : newList) { 45 th.setGroupId(groupId); 46 } 47 return newList; 48 } 49 satisfiedByThreshold( QualityMonitor wifiMonitor, QualityMonitor cellMonitor, boolean iwlanAvailable, boolean cellAvailable, int cellularAccessNetworkType)50 boolean satisfiedByThreshold( 51 QualityMonitor wifiMonitor, 52 QualityMonitor cellMonitor, 53 boolean iwlanAvailable, 54 boolean cellAvailable, 55 int cellularAccessNetworkType) { 56 if (mThresholds == null || mThresholds.isEmpty()) { 57 return false; 58 } 59 boolean omittedCellularAvailable = true; 60 for (Threshold th : mThresholds) { 61 if (th.getAccessNetwork() == AccessNetworkType.IWLAN) { 62 if (!satisfy(th, wifiMonitor, iwlanAvailable, AccessNetworkType.IWLAN)) { 63 return false; 64 } 65 } 66 if (th.getAccessNetwork() != AccessNetworkType.IWLAN) { 67 omittedCellularAvailable = false; 68 if (!satisfy(th, cellMonitor, cellAvailable, cellularAccessNetworkType)) { 69 return false; 70 } 71 } 72 } 73 if (omittedCellularAvailable && !cellAvailable) { 74 return false; 75 } 76 return true; 77 } 78 satisfy(Threshold th, QualityMonitor monitor, boolean available, int an)79 private boolean satisfy(Threshold th, QualityMonitor monitor, boolean available, int an) { 80 // availability 81 if (th.getMeasurementType() == QnsConstants.SIGNAL_MEASUREMENT_AVAILABILITY) { 82 if (th.getThreshold() == QnsConstants.SIGNAL_AVAILABLE 83 && available 84 && an == th.getAccessNetwork()) { 85 Log.d(mTag, "satisfy " + th.toShortString() + " currentQuality:Available"); 86 return true; 87 } 88 if (th.getThreshold() == QnsConstants.SIGNAL_UNAVAILABLE 89 && (!available || an != th.getAccessNetwork())) { 90 Log.d(mTag, "satisfy " + th.toShortString() + " currentQuality:Unavailable"); 91 return true; 92 } 93 Log.d(mTag, "not satisfy " + th.toShortString() + " available:" + available); 94 return false; 95 } 96 97 // measurement matching 98 if (th.getAccessNetwork() != an) { 99 return false; 100 } 101 int cq = monitor.getCurrentQuality(th.getAccessNetwork(), th.getMeasurementType()); 102 if (th.isMatching(cq)) { 103 Log.d(mTag, "satisfy " + th.toShortString() + " currentQuality:" + cq); 104 return true; 105 } else { 106 Log.d(mTag, "not satisfy " + th.toShortString() + " currentQuality:" + cq); 107 return false; 108 } 109 } 110 findUnmatchedThresholds( QualityMonitor wifiMonitor, QualityMonitor cellMonitor)111 List<Threshold> findUnmatchedThresholds( 112 QualityMonitor wifiMonitor, QualityMonitor cellMonitor) { 113 List<Threshold> tl = new ArrayList<>(); 114 if (mThresholds == null || mThresholds.isEmpty()) { 115 return tl; 116 } 117 118 for (Threshold th : mThresholds) { 119 if (th.getMeasurementType() == QnsConstants.SIGNAL_MEASUREMENT_AVAILABILITY) { 120 continue; 121 } 122 123 boolean isIwlan = th.getAccessNetwork() == AccessNetworkType.IWLAN; 124 QualityMonitor monitor = isIwlan ? wifiMonitor : cellMonitor; 125 int cq = monitor.getCurrentQuality(th.getAccessNetwork(), th.getMeasurementType()); 126 127 if (th.isMatching(cq)) { 128 Log.d(mTag, "Threshold " + th.toShortString() + " is matched. current:" + cq); 129 } else { 130 Log.d(mTag, "Threshold " + th.toShortString() + " is not matched. current:" + cq); 131 tl.add(th); 132 } 133 } 134 return tl; 135 } 136 hasWifiThresholdWithoutCellularCondition()137 boolean hasWifiThresholdWithoutCellularCondition() { 138 if (mThresholds == null || mThresholds.isEmpty()) { 139 return false; 140 } 141 boolean foundIwlanRssiThreshold = false; 142 boolean foundCellularUnavailable = false; 143 for (Threshold th : mThresholds) { 144 if (th.getMeasurementType() == SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI 145 && th.getAccessNetwork() == AccessNetworkType.IWLAN) { 146 foundIwlanRssiThreshold = true; 147 } 148 if (th.getMeasurementType() == QnsConstants.SIGNAL_MEASUREMENT_AVAILABILITY 149 && th.getThreshold() == QnsConstants.SIGNAL_UNAVAILABLE 150 && th.getAccessNetwork() != AccessNetworkType.IWLAN) { 151 foundCellularUnavailable = true; 152 } 153 } 154 return foundIwlanRssiThreshold && foundCellularUnavailable; 155 } 156 getThresholds(int accessNetworkType)157 List<Threshold> getThresholds(int accessNetworkType) { 158 List<Threshold> accessNetworkTypeThresholdList = new ArrayList<>(); 159 for (Threshold t : mThresholds) { 160 if (t.getAccessNetwork() == accessNetworkType) { 161 accessNetworkTypeThresholdList.add(t); 162 } 163 } 164 return accessNetworkTypeThresholdList; 165 } 166 toShortString()167 String toShortString() { 168 StringBuilder sb = new StringBuilder(); 169 sb.append("("); 170 if (mThresholds != null && mThresholds.size() > 0) { 171 for (Threshold th : mThresholds) { 172 sb.append(th.toShortString()).append(","); 173 } 174 sb.deleteCharAt(sb.lastIndexOf(",")); 175 } 176 sb.append(")"); 177 return sb.toString(); 178 } 179 identicalThreshold(List<Threshold> o)180 boolean identicalThreshold(List<Threshold> o) { 181 if (mThresholds == o) return true; 182 if (mThresholds == null || o == null) return false; 183 if (mThresholds.size() != o.size()) return false; 184 for (Threshold th : mThresholds) { 185 boolean found = false; 186 for (Threshold tho : o) { 187 if (th.identicalThreshold(tho)) { 188 found = true; 189 break; 190 } 191 } 192 if (!found) { 193 return false; 194 } 195 } 196 return true; 197 } 198 } 199