• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.net;
18 
19 import static android.content.pm.PackageManager.GET_SIGNATURES;
20 import static android.net.NetworkPolicy.CYCLE_NONE;
21 
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.pm.PackageManager;
25 import android.content.pm.PackageManager.NameNotFoundException;
26 import android.content.pm.Signature;
27 import android.os.RemoteException;
28 import android.os.UserHandle;
29 import android.util.DebugUtils;
30 
31 import com.google.android.collect.Sets;
32 
33 import java.util.Calendar;
34 import java.util.HashSet;
35 import java.util.TimeZone;
36 
37 /**
38  * Manager for creating and modifying network policy rules.
39  *
40  * {@hide}
41  */
42 public class NetworkPolicyManager {
43 
44     /* POLICY_* are masks and can be ORed */
45     /** No specific network policy, use system default. */
46     public static final int POLICY_NONE = 0x0;
47     /** Reject network usage on metered networks when application in background. */
48     public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1;
49     /** Allow network use (metered or not) in the background in battery save mode. */
50     public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
51 
52     /*
53      * Rules defining whether an uid has access to a network given its type (metered / non-metered).
54      *
55      * These rules are bits and can be used in bitmask operations; in particular:
56      * - rule & RULE_MASK_METERED: returns the metered-networks status.
57      * - rule & RULE_MASK_ALL: returns the all-networks status.
58      *
59      * The RULE_xxx_ALL rules applies to all networks (metered or non-metered), but on
60      * metered networks, the RULE_xxx_METERED rules should be checked first. For example,
61      * if the device is on Battery Saver Mode and Data Saver Mode simulatenously, and a uid
62      * is whitelisted for the former but not the latter, its status would be
63      * RULE_REJECT_METERED | RULE_ALLOW_ALL, meaning it could have access to non-metered
64      * networks but not to metered networks.
65      *
66      * See network-policy-restrictions.md for more info.
67      */
68     /** No specific rule was set */
69     public static final int RULE_NONE = 0;
70     /** Allow traffic on metered networks. */
71     public static final int RULE_ALLOW_METERED = 1 << 0;
72     /** Temporarily allow traffic on metered networks because app is on foreground. */
73     public static final int RULE_TEMPORARY_ALLOW_METERED = 1 << 1;
74     /** Reject traffic on metered networks. */
75     public static final int RULE_REJECT_METERED = 1 << 2;
76     /** Network traffic should be allowed on all networks (metered or non-metered), although
77      * metered-network restrictions could still apply. */
78     public static final int RULE_ALLOW_ALL = 1 << 5;
79     /** Reject traffic on all networks. */
80     public static final int RULE_REJECT_ALL = 1 << 6;
81     /** Mask used to get the {@code RULE_xxx_METERED} rules */
82     public static final int MASK_METERED_NETWORKS = 0b00001111;
83     /** Mask used to get the {@code RULE_xxx_ALL} rules */
84     public static final int MASK_ALL_NETWORKS     = 0b11110000;
85 
86     public static final int FIREWALL_RULE_DEFAULT = 0;
87     public static final int FIREWALL_RULE_ALLOW = 1;
88     public static final int FIREWALL_RULE_DENY = 2;
89 
90     public static final int FIREWALL_TYPE_WHITELIST = 0;
91     public static final int FIREWALL_TYPE_BLACKLIST = 1;
92 
93     public static final int FIREWALL_CHAIN_NONE = 0;
94     public static final int FIREWALL_CHAIN_DOZABLE = 1;
95     public static final int FIREWALL_CHAIN_STANDBY = 2;
96     public static final int FIREWALL_CHAIN_POWERSAVE = 3;
97 
98     public static final String FIREWALL_CHAIN_NAME_NONE = "none";
99     public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable";
100     public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
101     public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave";
102 
103     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
104 
105     /**
106      * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
107      * applies to.
108      */
109     public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
110 
111     private final Context mContext;
112     private INetworkPolicyManager mService;
113 
NetworkPolicyManager(Context context, INetworkPolicyManager service)114     public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
115         if (service == null) {
116             throw new IllegalArgumentException("missing INetworkPolicyManager");
117         }
118         mContext = context;
119         mService = service;
120     }
121 
from(Context context)122     public static NetworkPolicyManager from(Context context) {
123         return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
124     }
125 
126     /**
127      * Set policy flags for specific UID.
128      *
129      * @param policy {@link #POLICY_NONE} or combination of flags like
130      * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
131      */
setUidPolicy(int uid, int policy)132     public void setUidPolicy(int uid, int policy) {
133         try {
134             mService.setUidPolicy(uid, policy);
135         } catch (RemoteException e) {
136             throw e.rethrowFromSystemServer();
137         }
138     }
139 
140     /**
141      * Add policy flags for specific UID.  The given policy bits will be set for
142      * the uid.  Policy flags may be either
143      * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
144      */
addUidPolicy(int uid, int policy)145     public void addUidPolicy(int uid, int policy) {
146         try {
147             mService.addUidPolicy(uid, policy);
148         } catch (RemoteException e) {
149             throw e.rethrowFromSystemServer();
150         }
151     }
152 
153     /**
154      * Clear/remove policy flags for specific UID.  The given policy bits will be set for
155      * the uid.  Policy flags may be either
156      * {@link #POLICY_REJECT_METERED_BACKGROUND} or {@link #POLICY_ALLOW_BACKGROUND_BATTERY_SAVE}.
157      */
removeUidPolicy(int uid, int policy)158     public void removeUidPolicy(int uid, int policy) {
159         try {
160             mService.removeUidPolicy(uid, policy);
161         } catch (RemoteException e) {
162             throw e.rethrowFromSystemServer();
163         }
164     }
165 
getUidPolicy(int uid)166     public int getUidPolicy(int uid) {
167         try {
168             return mService.getUidPolicy(uid);
169         } catch (RemoteException e) {
170             throw e.rethrowFromSystemServer();
171         }
172     }
173 
getUidsWithPolicy(int policy)174     public int[] getUidsWithPolicy(int policy) {
175         try {
176             return mService.getUidsWithPolicy(policy);
177         } catch (RemoteException e) {
178             throw e.rethrowFromSystemServer();
179         }
180     }
181 
registerListener(INetworkPolicyListener listener)182     public void registerListener(INetworkPolicyListener listener) {
183         try {
184             mService.registerListener(listener);
185         } catch (RemoteException e) {
186             throw e.rethrowFromSystemServer();
187         }
188     }
189 
unregisterListener(INetworkPolicyListener listener)190     public void unregisterListener(INetworkPolicyListener listener) {
191         try {
192             mService.unregisterListener(listener);
193         } catch (RemoteException e) {
194             throw e.rethrowFromSystemServer();
195         }
196     }
197 
setNetworkPolicies(NetworkPolicy[] policies)198     public void setNetworkPolicies(NetworkPolicy[] policies) {
199         try {
200             mService.setNetworkPolicies(policies);
201         } catch (RemoteException e) {
202             throw e.rethrowFromSystemServer();
203         }
204     }
205 
getNetworkPolicies()206     public NetworkPolicy[] getNetworkPolicies() {
207         try {
208             return mService.getNetworkPolicies(mContext.getOpPackageName());
209         } catch (RemoteException e) {
210             throw e.rethrowFromSystemServer();
211         }
212     }
213 
setRestrictBackground(boolean restrictBackground)214     public void setRestrictBackground(boolean restrictBackground) {
215         try {
216             mService.setRestrictBackground(restrictBackground);
217         } catch (RemoteException e) {
218             throw e.rethrowFromSystemServer();
219         }
220     }
221 
getRestrictBackground()222     public boolean getRestrictBackground() {
223         try {
224             return mService.getRestrictBackground();
225         } catch (RemoteException e) {
226             throw e.rethrowFromSystemServer();
227         }
228     }
229 
230     /**
231      * Resets network policy settings back to factory defaults.
232      *
233      * @hide
234      */
factoryReset(String subscriber)235     public void factoryReset(String subscriber) {
236         try {
237             mService.factoryReset(subscriber);
238         } catch (RemoteException e) {
239             throw e.rethrowFromSystemServer();
240         }
241     }
242 
243     /**
244      * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
245      * example, if cycle day is 20th, and today is June 15th, it will return May
246      * 20th. When cycle day doesn't exist in current month, it snaps to the 1st
247      * of following month.
248      *
249      * @hide
250      */
computeLastCycleBoundary(long currentTime, NetworkPolicy policy)251     public static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
252         if (policy.cycleDay == CYCLE_NONE) {
253             throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
254         }
255 
256         final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(policy.cycleTimezone));
257         cal.setTimeInMillis(currentTime);
258         snapToCycleDay(cal, policy.cycleDay);
259 
260         if (cal.getTimeInMillis() >= currentTime) {
261             // Cycle boundary is beyond now, use last cycle boundary
262             cal.set(Calendar.DAY_OF_MONTH, 1);
263             cal.add(Calendar.MONTH, -1);
264             snapToCycleDay(cal, policy.cycleDay);
265         }
266 
267         return cal.getTimeInMillis();
268     }
269 
270     /** {@hide} */
computeNextCycleBoundary(long currentTime, NetworkPolicy policy)271     public static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
272         if (policy.cycleDay == CYCLE_NONE) {
273             throw new IllegalArgumentException("Unable to compute boundary without cycleDay");
274         }
275 
276         final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(policy.cycleTimezone));
277         cal.setTimeInMillis(currentTime);
278         snapToCycleDay(cal, policy.cycleDay);
279 
280         if (cal.getTimeInMillis() <= currentTime) {
281             // Cycle boundary is before now, use next cycle boundary
282             cal.set(Calendar.DAY_OF_MONTH, 1);
283             cal.add(Calendar.MONTH, 1);
284             snapToCycleDay(cal, policy.cycleDay);
285         }
286 
287         return cal.getTimeInMillis();
288     }
289 
290     /**
291      * Snap to the cycle day for the current month given; when cycle day doesn't
292      * exist, it snaps to last second of current month.
293      *
294      * @hide
295      */
snapToCycleDay(Calendar cal, int cycleDay)296     public static void snapToCycleDay(Calendar cal, int cycleDay) {
297         cal.set(Calendar.HOUR_OF_DAY, 0);
298         cal.set(Calendar.MINUTE, 0);
299         cal.set(Calendar.SECOND, 0);
300         if (cycleDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
301             cal.set(Calendar.DAY_OF_MONTH, 1);
302             cal.add(Calendar.MONTH, 1);
303             cal.add(Calendar.SECOND, -1);
304         } else {
305             cal.set(Calendar.DAY_OF_MONTH, cycleDay);
306         }
307     }
308 
309     /**
310      * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
311      * usually to protect critical system services.
312      */
313     @Deprecated
isUidValidForPolicy(Context context, int uid)314     public static boolean isUidValidForPolicy(Context context, int uid) {
315         // first, quick-reject non-applications
316         if (!UserHandle.isApp(uid)) {
317             return false;
318         }
319 
320         if (!ALLOW_PLATFORM_APP_POLICY) {
321             final PackageManager pm = context.getPackageManager();
322             final HashSet<Signature> systemSignature;
323             try {
324                 systemSignature = Sets.newHashSet(
325                         pm.getPackageInfo("android", GET_SIGNATURES).signatures);
326             } catch (NameNotFoundException e) {
327                 throw new RuntimeException("problem finding system signature", e);
328             }
329 
330             try {
331                 // reject apps signed with platform cert
332                 for (String packageName : pm.getPackagesForUid(uid)) {
333                     final HashSet<Signature> packageSignature = Sets.newHashSet(
334                             pm.getPackageInfo(packageName, GET_SIGNATURES).signatures);
335                     if (packageSignature.containsAll(systemSignature)) {
336                         return false;
337                     }
338                 }
339             } catch (NameNotFoundException e) {
340             }
341         }
342 
343         // nothing found above; we can apply policy to UID
344         return true;
345     }
346 
347     /*
348      * @hide
349      */
uidRulesToString(int uidRules)350     public static String uidRulesToString(int uidRules) {
351         final StringBuilder string = new StringBuilder().append(uidRules).append(" (");
352         if (uidRules == RULE_NONE) {
353             string.append("NONE");
354         } else {
355             string.append(DebugUtils.flagsToString(NetworkPolicyManager.class, "RULE_", uidRules));
356         }
357         string.append(")");
358         return string.toString();
359     }
360 }
361