1 /* 2 * Copyright (C) 2017 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.internal.telephony.dataconnection; 18 19 import java.util.HashSet; 20 21 /** 22 * The class to describe the reasons of allowing or disallowing to establish a data connection. 23 */ 24 public class DataConnectionReasons { 25 private HashSet<DataDisallowedReasonType> mDataDisallowedReasonSet = new HashSet<>(); 26 private DataAllowedReasonType mDataAllowedReason = DataAllowedReasonType.NONE; 27 DataConnectionReasons()28 public DataConnectionReasons() {} 29 add(DataDisallowedReasonType reason)30 void add(DataDisallowedReasonType reason) { 31 // Adding a disallowed reason will clean up the allowed reason because they are 32 // mutual exclusive. 33 mDataAllowedReason = DataAllowedReasonType.NONE; 34 mDataDisallowedReasonSet.add(reason); 35 } 36 add(DataAllowedReasonType reason)37 void add(DataAllowedReasonType reason) { 38 // Adding an allowed reason will clean up the disallowed reasons because they are 39 // mutual exclusive. 40 mDataDisallowedReasonSet.clear(); 41 42 // Only higher priority allowed reason can overwrite the old one. See 43 // DataAllowedReasonType for the oder. 44 if (reason.ordinal() > mDataAllowedReason.ordinal()) { 45 mDataAllowedReason = reason; 46 } 47 } 48 49 @Override toString()50 public String toString() { 51 StringBuilder reasonStr = new StringBuilder(); 52 if (mDataDisallowedReasonSet.size() > 0) { 53 reasonStr.append("Data disallowed, reasons:"); 54 for (DataDisallowedReasonType reason : mDataDisallowedReasonSet) { 55 reasonStr.append(" ").append(reason); 56 } 57 } else { 58 reasonStr.append("Data allowed, reason:"); 59 reasonStr.append(" ").append(mDataAllowedReason); 60 } 61 return reasonStr.toString(); 62 } 63 copyFrom(DataConnectionReasons reasons)64 void copyFrom(DataConnectionReasons reasons) { 65 this.mDataDisallowedReasonSet = reasons.mDataDisallowedReasonSet; 66 this.mDataAllowedReason = reasons.mDataAllowedReason; 67 } 68 allowed()69 boolean allowed() { 70 return mDataDisallowedReasonSet.size() == 0; 71 } 72 contains(DataDisallowedReasonType reason)73 boolean contains(DataDisallowedReasonType reason) { 74 return mDataDisallowedReasonSet.contains(reason); 75 } 76 77 /** 78 * Check if only one disallowed reason prevent data connection. 79 * 80 * @param reason The given reason to check 81 * @return True if the given reason is the only one that prevents data connection 82 */ containsOnly(DataDisallowedReasonType reason)83 public boolean containsOnly(DataDisallowedReasonType reason) { 84 return mDataDisallowedReasonSet.size() == 1 && contains(reason); 85 } 86 contains(DataAllowedReasonType reason)87 boolean contains(DataAllowedReasonType reason) { 88 return reason == mDataAllowedReason; 89 } 90 containsHardDisallowedReasons()91 boolean containsHardDisallowedReasons() { 92 for (DataDisallowedReasonType reason : mDataDisallowedReasonSet) { 93 if (reason.isHardReason()) { 94 return true; 95 } 96 } 97 return false; 98 } 99 100 // Disallowed reasons. There could be multiple reasons if data connection is not allowed. 101 public enum DataDisallowedReasonType { 102 // Soft failure reasons. Normally the reasons from users or policy settings. 103 DATA_DISABLED(false), // Data is disabled by the user or policy. 104 ROAMING_DISABLED(false), // Data roaming is disabled by the user. 105 DEFAULT_DATA_UNSELECTED(false), // Default data not selected. 106 107 // Belows are all hard failure reasons. 108 NOT_ATTACHED(true), 109 SIM_NOT_READY(true), 110 INVALID_PHONE_STATE(true), 111 CONCURRENT_VOICE_DATA_NOT_ALLOWED(true), 112 PS_RESTRICTED(true), 113 UNDESIRED_POWER_STATE(true), 114 INTERNAL_DATA_DISABLED(true), 115 RADIO_DISABLED_BY_CARRIER(true), 116 APN_NOT_CONNECTABLE(true), // Not in the right state for data call setup. 117 DATA_IS_CONNECTING(true), // Data is in connecting state. No need to send another setup 118 // request. 119 DATA_IS_DISCONNECTING(true), // Data is being disconnected. Telephony will retry after 120 // disconnected. 121 DATA_ALREADY_CONNECTED(true), // Data is already connected. No need to setup data again. 122 ON_IWLAN(true), 123 IN_ECBM(true), 124 ON_OTHER_TRANSPORT(true); // When data retry occurs, the given APN type's preferred 125 // transport might be already changed. In this case we 126 // should disallow data retry. 127 128 private boolean mIsHardReason; 129 isHardReason()130 boolean isHardReason() { 131 return mIsHardReason; 132 } 133 DataDisallowedReasonType(boolean isHardReason)134 DataDisallowedReasonType(boolean isHardReason) { 135 mIsHardReason = isHardReason; 136 } 137 } 138 139 // Data allowed reasons. There will be only one reason if data is allowed. 140 enum DataAllowedReasonType { 141 // Note that unlike disallowed reasons, we only have one allowed reason every time 142 // when we check data is allowed or not. The order of these allowed reasons is very 143 // important. The lower ones take precedence over the upper ones. 144 NONE, 145 NORMAL, 146 UNMETERED_APN, 147 RESTRICTED_REQUEST, 148 EMERGENCY_APN, 149 } 150 } 151