Home | History | Annotate | Download | only in net
      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