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