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