138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu/* 238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * Copyright (C) 2011 The Android Open Source Project 338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * 438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * Licensed under the Apache License, Version 2.0 (the "License"); 538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * you may not use this file except in compliance with the License. 638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * You may obtain a copy of the License at 738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * 838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * http://www.apache.org/licenses/LICENSE-2.0 938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * 1038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * Unless required by applicable law or agreed to in writing, software 1138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * distributed under the License is distributed on an "AS IS" BASIS, 1238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * See the License for the specific language governing permissions and 1438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * limitations under the License. 1538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu */ 1638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 1738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liupackage com.android.settingslib; 1838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 1938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport static android.net.NetworkPolicy.CYCLE_NONE; 2038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport static android.net.NetworkPolicy.LIMIT_DISABLED; 2138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport static android.net.NetworkPolicy.SNOOZE_NEVER; 2238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport static android.net.NetworkPolicy.WARNING_DISABLED; 2338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport static android.net.NetworkTemplate.MATCH_WIFI; 2438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport static com.android.internal.util.Preconditions.checkNotNull; 2538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 2638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.net.NetworkPolicy; 2738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.net.NetworkPolicyManager; 2838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.net.NetworkTemplate; 2938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.net.wifi.WifiInfo; 3038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.os.AsyncTask; 3138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.text.TextUtils; 3238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport android.text.format.Time; 3338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 3438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport com.google.android.collect.Lists; 3538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 3638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liuimport java.util.ArrayList; 3738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 3838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu/** 3938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * Utility class to modify list of {@link NetworkPolicy}. Specifically knows 4038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * about which policies can coexist. This editor offers thread safety when 4138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * talking with {@link NetworkPolicyManager}. 4238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * 4338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * @hide 4438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu */ 4538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liupublic class NetworkPolicyEditor { 4638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // TODO: be more robust when missing policies from service 4738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 4838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public static final boolean ENABLE_SPLIT_POLICIES = false; 4938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 5038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu private NetworkPolicyManager mPolicyManager; 5138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu private ArrayList<NetworkPolicy> mPolicies = Lists.newArrayList(); 5238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 5338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public NetworkPolicyEditor(NetworkPolicyManager policyManager) { 5438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicyManager = checkNotNull(policyManager); 5538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 5638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 5738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void read() { 5838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy[] policies = mPolicyManager.getNetworkPolicies(); 5938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 6038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu boolean modified = false; 6138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicies.clear(); 6238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu for (NetworkPolicy policy : policies) { 6338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // TODO: find better place to clamp these 6438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy.limitBytes < -1) { 6538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.limitBytes = LIMIT_DISABLED; 6638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu modified = true; 6738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 6838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy.warningBytes < -1) { 6938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.warningBytes = WARNING_DISABLED; 7038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu modified = true; 7138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 7238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 7338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicies.add(policy); 7438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 7538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 7638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // when we cleaned policies above, write back changes 7738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (modified) writeAsync(); 7838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 7938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 8038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void writeAsync() { 8138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // TODO: consider making more robust by passing through service 8238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy[] policies = mPolicies.toArray(new NetworkPolicy[mPolicies.size()]); 8338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu new AsyncTask<Void, Void, Void>() { 8438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu @Override 8538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu protected Void doInBackground(Void... params) { 8638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu write(policies); 8738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return null; 8838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 8938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu }.execute(); 9038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 9138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 9238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void write(NetworkPolicy[] policies) { 9338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicyManager.setNetworkPolicies(policies); 9438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 9538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 9638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public boolean hasLimitedPolicy(NetworkTemplate template) { 9738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getPolicy(template); 9838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return policy != null && policy.limitBytes != LIMIT_DISABLED; 9938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 10038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 10138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public NetworkPolicy getOrCreatePolicy(NetworkTemplate template) { 10238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu NetworkPolicy policy = getPolicy(template); 10338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy == null) { 10438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy = buildDefaultPolicy(template); 10538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicies.add(policy); 10638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 10738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return policy; 10838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 10938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 11038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public NetworkPolicy getPolicy(NetworkTemplate template) { 11138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu for (NetworkPolicy policy : mPolicies) { 11238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy.template.equals(template)) { 11338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return policy; 11438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 11538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 11638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return null; 11738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 11838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 11938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public NetworkPolicy getPolicyMaybeUnquoted(NetworkTemplate template) { 12038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu NetworkPolicy policy = getPolicy(template); 12138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy != null) { 12238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return policy; 12338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else { 12438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return getPolicy(buildUnquotedNetworkTemplate(template)); 12538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 12638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 12738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 12838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu @Deprecated 12938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu private static NetworkPolicy buildDefaultPolicy(NetworkTemplate template) { 13038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // TODO: move this into framework to share with NetworkPolicyManagerService 13138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final int cycleDay; 13238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final String cycleTimezone; 13338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final boolean metered; 13438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 13538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (template.getMatchRule() == MATCH_WIFI) { 13638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu cycleDay = CYCLE_NONE; 13738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu cycleTimezone = Time.TIMEZONE_UTC; 13838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu metered = false; 13938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else { 14038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final Time time = new Time(); 14138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu time.setToNow(); 14238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu cycleDay = time.monthDay; 14338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu cycleTimezone = time.timezone; 14438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu metered = true; 14538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 14638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 14738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return new NetworkPolicy(template, cycleDay, cycleTimezone, WARNING_DISABLED, 14838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, metered, true); 14938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 15038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 15138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public int getPolicyCycleDay(NetworkTemplate template) { 15238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getPolicy(template); 15338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return (policy != null) ? policy.cycleDay : -1; 15438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 15538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 15638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void setPolicyCycleDay(NetworkTemplate template, int cycleDay, String cycleTimezone) { 15738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getOrCreatePolicy(template); 15838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.cycleDay = cycleDay; 15938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.cycleTimezone = cycleTimezone; 16038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.inferred = false; 16138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.clearSnooze(); 16238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu writeAsync(); 16338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 16438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 16538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public long getPolicyWarningBytes(NetworkTemplate template) { 16638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getPolicy(template); 16738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return (policy != null) ? policy.warningBytes : WARNING_DISABLED; 16838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 16938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 17038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void setPolicyWarningBytes(NetworkTemplate template, long warningBytes) { 17138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getOrCreatePolicy(template); 17238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.warningBytes = warningBytes; 17338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.inferred = false; 17438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.clearSnooze(); 17538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu writeAsync(); 17638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 17738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 17838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public long getPolicyLimitBytes(NetworkTemplate template) { 17938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getPolicy(template); 18038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return (policy != null) ? policy.limitBytes : LIMIT_DISABLED; 18138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 18238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 18338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void setPolicyLimitBytes(NetworkTemplate template, long limitBytes) { 18438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy policy = getOrCreatePolicy(template); 18538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.limitBytes = limitBytes; 18638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.inferred = false; 18738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.clearSnooze(); 18838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu writeAsync(); 18938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 19038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 19138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public boolean getPolicyMetered(NetworkTemplate template) { 19238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu NetworkPolicy policy = getPolicy(template); 19338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy != null) { 19438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return policy.metered; 19538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else { 19638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return false; 19738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 19838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 19938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 20038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu public void setPolicyMetered(NetworkTemplate template, boolean metered) { 20138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu boolean modified = false; 20238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 20338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu NetworkPolicy policy = getPolicy(template); 20438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (metered) { 20538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy == null) { 20638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy = buildDefaultPolicy(template); 20738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.metered = true; 20838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.inferred = false; 20938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicies.add(policy); 21038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu modified = true; 21138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else if (!policy.metered) { 21238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.metered = true; 21338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.inferred = false; 21438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu modified = true; 21538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 21638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 21738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else { 21838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (policy == null) { 21938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // ignore when policy doesn't exist 22038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else if (policy.metered) { 22138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.metered = false; 22238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu policy.inferred = false; 22338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu modified = true; 22438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 22538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 22638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 22738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu // Remove legacy unquoted policies while we're here 22838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkTemplate unquoted = buildUnquotedNetworkTemplate(template); 22938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final NetworkPolicy unquotedPolicy = getPolicy(unquoted); 23038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (unquotedPolicy != null) { 23138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu mPolicies.remove(unquotedPolicy); 23238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu modified = true; 23338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 23438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 23538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (modified) writeAsync(); 23638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 23738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu 23838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu /** 23938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * Build a revised {@link NetworkTemplate} that matches the same rule, but 24038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * with an unquoted {@link NetworkTemplate#getNetworkId()}. Used to work 24138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu * around legacy bugs. 24238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu */ 24338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) { 24438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (template == null) return null; 24538e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final String networkId = template.getNetworkId(); 24638e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu final String strippedNetworkId = WifiInfo.removeDoubleQuotes(networkId); 24738e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu if (!TextUtils.equals(strippedNetworkId, networkId)) { 24838e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return new NetworkTemplate( 24938e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu template.getMatchRule(), template.getSubscriberId(), strippedNetworkId); 25038e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } else { 25138e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu return null; 25238e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 25338e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu } 25438e932b37aea8d2f6866c3c879afa188587bcde3Wei Liu} 255