• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.settingslib;
18 
19 import static android.net.NetworkPolicy.CYCLE_NONE;
20 import static android.net.NetworkPolicy.LIMIT_DISABLED;
21 import static android.net.NetworkPolicy.SNOOZE_NEVER;
22 import static android.net.NetworkPolicy.WARNING_DISABLED;
23 import static android.net.NetworkTemplate.MATCH_WIFI;
24 import static com.android.internal.util.Preconditions.checkNotNull;
25 
26 import android.net.NetworkPolicy;
27 import android.net.NetworkPolicyManager;
28 import android.net.NetworkTemplate;
29 import android.net.wifi.WifiInfo;
30 import android.os.AsyncTask;
31 import android.text.TextUtils;
32 import android.text.format.Time;
33 
34 import com.google.android.collect.Lists;
35 
36 import java.util.ArrayList;
37 
38 /**
39  * Utility class to modify list of {@link NetworkPolicy}. Specifically knows
40  * about which policies can coexist. This editor offers thread safety when
41  * talking with {@link NetworkPolicyManager}.
42  *
43  * @hide
44  */
45 public class NetworkPolicyEditor {
46     // TODO: be more robust when missing policies from service
47 
48     public static final boolean ENABLE_SPLIT_POLICIES = false;
49 
50     private NetworkPolicyManager mPolicyManager;
51     private ArrayList<NetworkPolicy> mPolicies = Lists.newArrayList();
52 
NetworkPolicyEditor(NetworkPolicyManager policyManager)53     public NetworkPolicyEditor(NetworkPolicyManager policyManager) {
54         mPolicyManager = checkNotNull(policyManager);
55     }
56 
read()57     public void read() {
58         final NetworkPolicy[] policies = mPolicyManager.getNetworkPolicies();
59 
60         boolean modified = false;
61         mPolicies.clear();
62         for (NetworkPolicy policy : policies) {
63             // TODO: find better place to clamp these
64             if (policy.limitBytes < -1) {
65                 policy.limitBytes = LIMIT_DISABLED;
66                 modified = true;
67             }
68             if (policy.warningBytes < -1) {
69                 policy.warningBytes = WARNING_DISABLED;
70                 modified = true;
71             }
72 
73             mPolicies.add(policy);
74         }
75 
76         // when we cleaned policies above, write back changes
77         if (modified) writeAsync();
78     }
79 
writeAsync()80     public void writeAsync() {
81         // TODO: consider making more robust by passing through service
82         final NetworkPolicy[] policies = mPolicies.toArray(new NetworkPolicy[mPolicies.size()]);
83         new AsyncTask<Void, Void, Void>() {
84             @Override
85             protected Void doInBackground(Void... params) {
86                 write(policies);
87                 return null;
88             }
89         }.execute();
90     }
91 
write(NetworkPolicy[] policies)92     public void write(NetworkPolicy[] policies) {
93         mPolicyManager.setNetworkPolicies(policies);
94     }
95 
hasLimitedPolicy(NetworkTemplate template)96     public boolean hasLimitedPolicy(NetworkTemplate template) {
97         final NetworkPolicy policy = getPolicy(template);
98         return policy != null && policy.limitBytes != LIMIT_DISABLED;
99     }
100 
getOrCreatePolicy(NetworkTemplate template)101     public NetworkPolicy getOrCreatePolicy(NetworkTemplate template) {
102         NetworkPolicy policy = getPolicy(template);
103         if (policy == null) {
104             policy = buildDefaultPolicy(template);
105             mPolicies.add(policy);
106         }
107         return policy;
108     }
109 
getPolicy(NetworkTemplate template)110     public NetworkPolicy getPolicy(NetworkTemplate template) {
111         for (NetworkPolicy policy : mPolicies) {
112             if (policy.template.equals(template)) {
113                 return policy;
114             }
115         }
116         return null;
117     }
118 
getPolicyMaybeUnquoted(NetworkTemplate template)119     public NetworkPolicy getPolicyMaybeUnquoted(NetworkTemplate template) {
120         NetworkPolicy policy = getPolicy(template);
121         if (policy != null) {
122             return policy;
123         } else {
124             return getPolicy(buildUnquotedNetworkTemplate(template));
125         }
126     }
127 
128     @Deprecated
buildDefaultPolicy(NetworkTemplate template)129     private static NetworkPolicy buildDefaultPolicy(NetworkTemplate template) {
130         // TODO: move this into framework to share with NetworkPolicyManagerService
131         final int cycleDay;
132         final String cycleTimezone;
133         final boolean metered;
134 
135         if (template.getMatchRule() == MATCH_WIFI) {
136             cycleDay = CYCLE_NONE;
137             cycleTimezone = Time.TIMEZONE_UTC;
138             metered = false;
139         } else {
140             final Time time = new Time();
141             time.setToNow();
142             cycleDay = time.monthDay;
143             cycleTimezone = time.timezone;
144             metered = true;
145         }
146 
147         return new NetworkPolicy(template, cycleDay, cycleTimezone, WARNING_DISABLED,
148                 LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, metered, true);
149     }
150 
getPolicyCycleDay(NetworkTemplate template)151     public int getPolicyCycleDay(NetworkTemplate template) {
152         final NetworkPolicy policy = getPolicy(template);
153         return (policy != null) ? policy.cycleDay : -1;
154     }
155 
setPolicyCycleDay(NetworkTemplate template, int cycleDay, String cycleTimezone)156     public void setPolicyCycleDay(NetworkTemplate template, int cycleDay, String cycleTimezone) {
157         final NetworkPolicy policy = getOrCreatePolicy(template);
158         policy.cycleDay = cycleDay;
159         policy.cycleTimezone = cycleTimezone;
160         policy.inferred = false;
161         policy.clearSnooze();
162         writeAsync();
163     }
164 
getPolicyWarningBytes(NetworkTemplate template)165     public long getPolicyWarningBytes(NetworkTemplate template) {
166         final NetworkPolicy policy = getPolicy(template);
167         return (policy != null) ? policy.warningBytes : WARNING_DISABLED;
168     }
169 
setPolicyWarningBytes(NetworkTemplate template, long warningBytes)170     public void setPolicyWarningBytes(NetworkTemplate template, long warningBytes) {
171         final NetworkPolicy policy = getOrCreatePolicy(template);
172         policy.warningBytes = warningBytes;
173         policy.inferred = false;
174         policy.clearSnooze();
175         writeAsync();
176     }
177 
getPolicyLimitBytes(NetworkTemplate template)178     public long getPolicyLimitBytes(NetworkTemplate template) {
179         final NetworkPolicy policy = getPolicy(template);
180         return (policy != null) ? policy.limitBytes : LIMIT_DISABLED;
181     }
182 
setPolicyLimitBytes(NetworkTemplate template, long limitBytes)183     public void setPolicyLimitBytes(NetworkTemplate template, long limitBytes) {
184         final NetworkPolicy policy = getOrCreatePolicy(template);
185         policy.limitBytes = limitBytes;
186         policy.inferred = false;
187         policy.clearSnooze();
188         writeAsync();
189     }
190 
getPolicyMetered(NetworkTemplate template)191     public boolean getPolicyMetered(NetworkTemplate template) {
192         NetworkPolicy policy = getPolicy(template);
193         if (policy != null) {
194             return policy.metered;
195         } else {
196             return false;
197         }
198     }
199 
setPolicyMetered(NetworkTemplate template, boolean metered)200     public void setPolicyMetered(NetworkTemplate template, boolean metered) {
201         boolean modified = false;
202 
203         NetworkPolicy policy = getPolicy(template);
204         if (metered) {
205             if (policy == null) {
206                 policy = buildDefaultPolicy(template);
207                 policy.metered = true;
208                 policy.inferred = false;
209                 mPolicies.add(policy);
210                 modified = true;
211             } else if (!policy.metered) {
212                 policy.metered = true;
213                 policy.inferred = false;
214                 modified = true;
215             }
216 
217         } else {
218             if (policy == null) {
219                 // ignore when policy doesn't exist
220             } else if (policy.metered) {
221                 policy.metered = false;
222                 policy.inferred = false;
223                 modified = true;
224             }
225         }
226 
227         // Remove legacy unquoted policies while we're here
228         final NetworkTemplate unquoted = buildUnquotedNetworkTemplate(template);
229         final NetworkPolicy unquotedPolicy = getPolicy(unquoted);
230         if (unquotedPolicy != null) {
231             mPolicies.remove(unquotedPolicy);
232             modified = true;
233         }
234 
235         if (modified) writeAsync();
236     }
237 
238     /**
239      * Build a revised {@link NetworkTemplate} that matches the same rule, but
240      * with an unquoted {@link NetworkTemplate#getNetworkId()}. Used to work
241      * around legacy bugs.
242      */
buildUnquotedNetworkTemplate(NetworkTemplate template)243     private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) {
244         if (template == null) return null;
245         final String networkId = template.getNetworkId();
246         final String strippedNetworkId = WifiInfo.removeDoubleQuotes(networkId);
247         if (!TextUtils.equals(strippedNetworkId, networkId)) {
248             return new NetworkTemplate(
249                     template.getMatchRule(), template.getSubscriberId(), strippedNetworkId);
250         } else {
251             return null;
252         }
253     }
254 }
255