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; 20 import android.util.Log; 21 22 import java.util.ArrayList; 23 import java.util.List; 24 import java.util.Objects; 25 import java.util.concurrent.atomic.AtomicInteger; 26 27 class AccessNetworkSelectionPolicy { 28 private static final AtomicInteger sAid = new AtomicInteger(); 29 30 private final int mPolicyId; 31 private final int mNetCapability; 32 private final int mTargetTransportType; // AccessNetworkConstants WWAN or WLAN 33 private final PreCondition mPreCondition; 34 private final PostCondition mPostCondition; 35 private final String mLogTag; 36 private ThresholdGroup mLastMatchedThresholdGroup; 37 AccessNetworkSelectionPolicy( int netCapability, int targetTransportType, PreCondition preCondition, List<ThresholdGroup> thgroups)38 AccessNetworkSelectionPolicy( 39 int netCapability, 40 int targetTransportType, 41 PreCondition preCondition, 42 List<ThresholdGroup> thgroups) { 43 mPolicyId = sAid.getAndIncrement(); 44 mLogTag = 45 QnsConstants.QNS_TAG 46 + "_" 47 + AccessNetworkSelectionPolicy.class.getSimpleName() 48 + "_" 49 + mPolicyId 50 + "_" 51 + QnsUtils.getNameOfNetCapability(netCapability); 52 mNetCapability = netCapability; 53 mTargetTransportType = targetTransportType; 54 mPreCondition = preCondition; 55 mPostCondition = new PostCondition(thgroups); 56 } 57 58 @Override toString()59 public String toString() { 60 return "[AnsPolicy" 61 + mPolicyId 62 + ":" 63 + QnsUtils.getNameOfNetCapability(mNetCapability) 64 + "]" 65 + QnsConstants.transportTypeToString(mTargetTransportType) 66 + "," 67 + mPreCondition.toString() 68 + mPostCondition.toString(); 69 } 70 getTargetTransportType()71 int getTargetTransportType() { 72 return mTargetTransportType; 73 } 74 satisfyPrecondition(PreCondition preCondition)75 boolean satisfyPrecondition(PreCondition preCondition) { 76 return mPreCondition.satisfied(preCondition); 77 } 78 satisfiedByThreshold( QualityMonitor wifiMonitor, QualityMonitor cellMonitor, boolean iwlanAvailable, boolean cellAvailable, int cellularAccessNetworkType)79 boolean satisfiedByThreshold( 80 QualityMonitor wifiMonitor, 81 QualityMonitor cellMonitor, 82 boolean iwlanAvailable, 83 boolean cellAvailable, 84 int cellularAccessNetworkType) { 85 if (wifiMonitor == null || cellMonitor == null) { 86 return false; 87 } 88 return mPostCondition.satisfiedByThreshold( 89 wifiMonitor, cellMonitor, iwlanAvailable, cellAvailable, cellularAccessNetworkType); 90 } 91 findUnmatchedThresholds( QualityMonitor wifiMonitor, QualityMonitor cellMonitor)92 List<Threshold> findUnmatchedThresholds( 93 QualityMonitor wifiMonitor, QualityMonitor cellMonitor) { 94 if (wifiMonitor == null || cellMonitor == null) { 95 return null; 96 } 97 return mPostCondition.findUnmatchedThresholds(wifiMonitor, cellMonitor); 98 } 99 log(String s)100 protected void log(String s) { 101 Log.d(mLogTag, s); 102 } 103 hasWifiThresholdWithoutCellularCondition()104 boolean hasWifiThresholdWithoutCellularCondition() { 105 return mPostCondition.hasWifiThresholdWithoutCellularCondition(); 106 } 107 satisfiedWithWifiLowSignalStrength()108 boolean satisfiedWithWifiLowSignalStrength() { 109 List<Threshold> thList = 110 mLastMatchedThresholdGroup.getThresholds( 111 AccessNetworkConstants.AccessNetworkType.IWLAN); 112 if (thList != null) { 113 for (Threshold th : thList) { 114 if (th.getMatchType() == QnsConstants.THRESHOLD_EQUAL_OR_SMALLER) { 115 log("satisfiedWithWifiLowSignalStrength"); 116 return true; 117 } 118 } 119 } 120 return false; 121 } 122 getPreCondition()123 PreCondition getPreCondition() { 124 return mPreCondition; 125 } 126 127 protected static class PreCondition { 128 @QnsConstants.QnsCallType private final int mCallType; 129 @QnsConstants.WfcModePreference private final int mPreference; 130 @QnsConstants.CellularCoverage private final int mCoverage; 131 PreCondition( @nsConstants.QnsCallType int callType, @QnsConstants.WfcModePreference int preference, @QnsConstants.CellularCoverage int coverage)132 protected PreCondition( 133 @QnsConstants.QnsCallType int callType, 134 @QnsConstants.WfcModePreference int preference, 135 @QnsConstants.CellularCoverage int coverage) { 136 mCallType = callType; 137 mCoverage = coverage; 138 mPreference = preference; 139 } 140 satisfied(PreCondition preCondition)141 boolean satisfied(PreCondition preCondition) { 142 return (mCallType == preCondition.mCallType) 143 && (mCoverage == preCondition.mCoverage) 144 && (mPreference == preCondition.mPreference); 145 } 146 getCallType()147 int getCallType() { 148 return mCallType; 149 } 150 getPreference()151 int getPreference() { 152 return mPreference; 153 } 154 getCoverage()155 int getCoverage() { 156 return mCoverage; 157 } 158 159 @Override toString()160 public String toString() { 161 return QnsConstants.callTypeToString(mCallType) 162 + "," 163 + QnsConstants.preferenceToString(mPreference) 164 + "," 165 + QnsConstants.coverageToString(mCoverage) 166 + ","; 167 } 168 169 @Override equals(Object o)170 public boolean equals(Object o) { 171 if (this == o) return true; 172 if (!(o instanceof PreCondition)) return false; 173 PreCondition that = (PreCondition) o; 174 return mCallType == that.mCallType 175 && mPreference == that.mPreference 176 && mCoverage == that.mCoverage; 177 } 178 179 @Override hashCode()180 public int hashCode() { 181 return Objects.hash(mCallType, mPreference, mCoverage); 182 } 183 } 184 185 protected static class GuardingPreCondition extends PreCondition { 186 @QnsConstants.QnsGuarding private final int mGuarding; 187 GuardingPreCondition( @nsConstants.QnsCallType int callType, @QnsConstants.WfcModePreference int preference, @QnsConstants.CellularCoverage int coverage, @QnsConstants.QnsGuarding int guarding)188 protected GuardingPreCondition( 189 @QnsConstants.QnsCallType int callType, 190 @QnsConstants.WfcModePreference int preference, 191 @QnsConstants.CellularCoverage int coverage, 192 @QnsConstants.QnsGuarding int guarding) { 193 super(callType, preference, coverage); 194 mGuarding = guarding; 195 } 196 satisfied(PreCondition preCondition)197 boolean satisfied(PreCondition preCondition) { 198 if (preCondition instanceof GuardingPreCondition) { 199 return super.satisfied(preCondition) 200 && mGuarding == ((GuardingPreCondition) preCondition).mGuarding; 201 } 202 return super.satisfied(preCondition); 203 } 204 getGuarding()205 int getGuarding() { 206 return mGuarding; 207 } 208 209 @Override toString()210 public String toString() { 211 return QnsConstants.guardingToString(mGuarding) + "," + super.toString(); 212 } 213 214 @Override equals(Object o)215 public boolean equals(Object o) { 216 if (this == o) return true; 217 if (!(o instanceof GuardingPreCondition)) return false; 218 if (!super.equals(o)) return false; 219 GuardingPreCondition that = (GuardingPreCondition) o; 220 return mGuarding == that.mGuarding; 221 } 222 223 @Override hashCode()224 public int hashCode() { 225 return Objects.hash(super.hashCode(), mGuarding); 226 } 227 } 228 229 protected class PostCondition { 230 private final List<ThresholdGroup> mThresholdGroups; 231 PostCondition(List<ThresholdGroup> thGroups)232 protected PostCondition(List<ThresholdGroup> thGroups) { 233 mThresholdGroups = thGroups; 234 } 235 satisfiedByThreshold( QualityMonitor wifiMonitor, QualityMonitor cellMonitor, boolean iwlanAvailable, boolean cellAvailable, int cellularAccessNetworkType)236 protected boolean satisfiedByThreshold( 237 QualityMonitor wifiMonitor, 238 QualityMonitor cellMonitor, 239 boolean iwlanAvailable, 240 boolean cellAvailable, 241 int cellularAccessNetworkType) { 242 // if one of thresholdgroup satisfies, return true; 243 if (mThresholdGroups != null) { 244 for (ThresholdGroup thgroup : mThresholdGroups) { 245 if (thgroup.satisfiedByThreshold( 246 wifiMonitor, 247 cellMonitor, 248 iwlanAvailable, 249 cellAvailable, 250 cellularAccessNetworkType)) { 251 mLastMatchedThresholdGroup = thgroup; 252 return true; 253 } 254 } 255 } 256 return false; 257 } 258 findUnmatchedThresholds( QualityMonitor wifiMonitor, QualityMonitor cellMonitor)259 protected List<Threshold> findUnmatchedThresholds( 260 QualityMonitor wifiMonitor, QualityMonitor cellMonitor) { 261 List<Threshold> unmatchedThresholds = new ArrayList<>(); 262 if (mThresholdGroups != null) { 263 for (ThresholdGroup thgroup : mThresholdGroups) { 264 unmatchedThresholds.addAll( 265 thgroup.findUnmatchedThresholds(wifiMonitor, cellMonitor)); 266 } 267 } 268 return unmatchedThresholds; 269 } 270 hasWifiThresholdWithoutCellularCondition()271 boolean hasWifiThresholdWithoutCellularCondition() { 272 if (mThresholdGroups == null) { 273 return false; 274 } 275 for (ThresholdGroup thresholdGroup : mThresholdGroups) { 276 if (thresholdGroup.hasWifiThresholdWithoutCellularCondition()) { 277 return true; 278 } 279 } 280 return false; 281 } 282 283 @Override toString()284 public String toString() { 285 StringBuilder sb = new StringBuilder(); 286 if (mThresholdGroups != null && mThresholdGroups.size() > 0) { 287 for (ThresholdGroup thgroup : mThresholdGroups) { 288 sb.append(thgroup.toShortString()).append(","); 289 } 290 sb.deleteCharAt(sb.lastIndexOf(",")); 291 } 292 return sb.toString(); 293 } 294 } 295 } 296