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