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 
106         // Belows are all hard failure reasons.
107         NOT_ATTACHED(true),
108         RECORD_NOT_LOADED(true),
109         INVALID_PHONE_STATE(true),
110         CONCURRENT_VOICE_DATA_NOT_ALLOWED(true),
111         PS_RESTRICTED(true),
112         UNDESIRED_POWER_STATE(true),
113         INTERNAL_DATA_DISABLED(true),
114         DEFAULT_DATA_UNSELECTED(true),
115         RADIO_DISABLED_BY_CARRIER(true),
116         APN_NOT_CONNECTABLE(true),
117         ON_IWLAN(true),
118         IN_ECBM(true);
119 
120         private boolean mIsHardReason;
121 
isHardReason()122         boolean isHardReason() {
123             return mIsHardReason;
124         }
125 
DataDisallowedReasonType(boolean isHardReason)126         DataDisallowedReasonType(boolean isHardReason) {
127             mIsHardReason = isHardReason;
128         }
129     }
130 
131     // Data allowed reasons. There will be only one reason if data is allowed.
132     enum DataAllowedReasonType {
133         // Note that unlike disallowed reasons, we only have one allowed reason every time
134         // when we check data is allowed or not. The order of these allowed reasons is very
135         // important. The lower ones take precedence over the upper ones.
136         NONE,
137         NORMAL,
138         UNMETERED_APN,
139         RESTRICTED_REQUEST,
140         EMERGENCY_APN,
141     }
142 }
143