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