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