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 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SystemService;
25 import android.app.ActivityManager;
26 import android.compat.annotation.UnsupportedAppUsage;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.pm.PackageManager;
30 import android.content.pm.PackageManager.NameNotFoundException;
31 import android.content.pm.Signature;
32 import android.net.wifi.WifiConfiguration;
33 import android.net.wifi.WifiInfo;
34 import android.os.Build;
35 import android.os.RemoteException;
36 import android.os.UserHandle;
37 import android.telephony.SubscriptionPlan;
38 import android.util.DebugUtils;
39 import android.util.Pair;
40 import android.util.Range;
41 
42 import com.google.android.collect.Sets;
43 
44 import java.lang.annotation.Retention;
45 import java.lang.annotation.RetentionPolicy;
46 import java.time.ZonedDateTime;
47 import java.util.HashSet;
48 import java.util.Iterator;
49 import java.util.Map;
50 import java.util.concurrent.ConcurrentHashMap;
51 
52 /**
53  * Manager for creating and modifying network policy rules.
54  *
55  * @hide
56  */
57 @SystemService(Context.NETWORK_POLICY_SERVICE)
58 public class NetworkPolicyManager {
59 
60     /* POLICY_* are masks and can be ORed, although currently they are not.*/
61     /**
62      * No specific network policy, use system default.
63      * @hide
64      */
65     public static final int POLICY_NONE = 0x0;
66     /**
67      * Reject network usage on metered networks when application in background.
68      * @hide
69      */
70     public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1;
71     /**
72      * Allow metered network use in the background even when in data usage save mode.
73      * @hide
74      */
75     public static final int POLICY_ALLOW_METERED_BACKGROUND = 0x4;
76 
77     /*
78      * Rules defining whether an uid has access to a network given its type (metered / non-metered).
79      *
80      * These rules are bits and can be used in bitmask operations; in particular:
81      * - rule & RULE_MASK_METERED: returns the metered-networks status.
82      * - rule & RULE_MASK_ALL: returns the all-networks status.
83      *
84      * The RULE_xxx_ALL rules applies to all networks (metered or non-metered), but on
85      * metered networks, the RULE_xxx_METERED rules should be checked first. For example,
86      * if the device is on Battery Saver Mode and Data Saver Mode simulatenously, and a uid
87      * is whitelisted for the former but not the latter, its status would be
88      * RULE_REJECT_METERED | RULE_ALLOW_ALL, meaning it could have access to non-metered
89      * networks but not to metered networks.
90      *
91      * See network-policy-restrictions.md for more info.
92      */
93 
94     /**
95      * No specific rule was set
96      * @hide
97      */
98     public static final int RULE_NONE = 0;
99     /**
100      * Allow traffic on metered networks.
101      * @hide
102      */
103     public static final int RULE_ALLOW_METERED = 1 << 0;
104     /**
105      * Temporarily allow traffic on metered networks because app is on foreground.
106      * @hide
107      */
108     public static final int RULE_TEMPORARY_ALLOW_METERED = 1 << 1;
109     /**
110      * Reject traffic on metered networks.
111      * @hide
112      */
113     public static final int RULE_REJECT_METERED = 1 << 2;
114     /**
115      * Network traffic should be allowed on all networks (metered or non-metered), although
116      * metered-network restrictions could still apply.
117      * @hide
118      */
119     public static final int RULE_ALLOW_ALL = 1 << 5;
120     /**
121      * Reject traffic on all networks.
122      * @hide
123      */
124     public static final int RULE_REJECT_ALL = 1 << 6;
125 
126     /**
127      * Mask used to get the {@code RULE_xxx_METERED} rules
128      * @hide
129      */
130     public static final int MASK_METERED_NETWORKS = 0b00001111;
131     /**
132      * Mask used to get the {@code RULE_xxx_ALL} rules
133      * @hide
134      */
135     public static final int MASK_ALL_NETWORKS     = 0b11110000;
136 
137     /** @hide */
138     public static final int FIREWALL_RULE_DEFAULT = 0;
139     /** @hide */
140     public static final String FIREWALL_CHAIN_NAME_NONE = "none";
141     /** @hide */
142     public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable";
143     /** @hide */
144     public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
145     /** @hide */
146     public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave";
147 
148     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
149 
150     /** @hide */
151     public static final int FOREGROUND_THRESHOLD_STATE =
152             ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
153 
154     /**
155      * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
156      * applies to.
157      * @hide
158      */
159     public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
160 
161     /**
162      * Mask used to check if an override value is marked as unmetered.
163      * @hide
164      */
165     public static final int SUBSCRIPTION_OVERRIDE_UNMETERED = 1 << 0;
166 
167     /**
168      * Mask used to check if an override value is marked as congested.
169      * @hide
170      */
171     public static final int SUBSCRIPTION_OVERRIDE_CONGESTED = 1 << 1;
172 
173     /**
174      * @hide
175      */
176     @Retention(RetentionPolicy.SOURCE)
177     @IntDef(flag = true, prefix = { "SUBSCRIPTION_OVERRIDE_" }, value = {
178         SUBSCRIPTION_OVERRIDE_UNMETERED,
179         SUBSCRIPTION_OVERRIDE_CONGESTED
180     })
181     public @interface SubscriptionOverrideMask {}
182 
183     private final Context mContext;
184     @UnsupportedAppUsage
185     private INetworkPolicyManager mService;
186 
187     private final Map<SubscriptionCallback, SubscriptionCallbackProxy>
188             mCallbackMap = new ConcurrentHashMap<>();
189 
190     /** @hide */
NetworkPolicyManager(Context context, INetworkPolicyManager service)191     public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
192         if (service == null) {
193             throw new IllegalArgumentException("missing INetworkPolicyManager");
194         }
195         mContext = context;
196         mService = service;
197     }
198 
199     /** @hide */
200     @UnsupportedAppUsage
from(Context context)201     public static NetworkPolicyManager from(Context context) {
202         return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
203     }
204 
205     /**
206      * Set policy flags for specific UID.
207      *
208      * @param policy should be {@link #POLICY_NONE} or any combination of {@code POLICY_} flags,
209      *     although it is not validated.
210      * @hide
211      */
212     @UnsupportedAppUsage
setUidPolicy(int uid, int policy)213     public void setUidPolicy(int uid, int policy) {
214         try {
215             mService.setUidPolicy(uid, policy);
216         } catch (RemoteException e) {
217             throw e.rethrowFromSystemServer();
218         }
219     }
220 
221     /**
222      * Add policy flags for specific UID.
223      *
224      * <p>The given policy bits will be set for the uid.
225      *
226      * @param policy should be {@link #POLICY_NONE} or any combination of {@code POLICY_} flags,
227      *     although it is not validated.
228      * @hide
229      */
addUidPolicy(int uid, int policy)230     public void addUidPolicy(int uid, int policy) {
231         try {
232             mService.addUidPolicy(uid, policy);
233         } catch (RemoteException e) {
234             throw e.rethrowFromSystemServer();
235         }
236     }
237 
238     /**
239      * Clear/remove policy flags for specific UID.
240      *
241      * <p>The given policy bits will be set for the uid.
242      *
243      * @param policy should be {@link #POLICY_NONE} or any combination of {@code POLICY_} flags,
244      *     although it is not validated.
245      * @hide
246      */
removeUidPolicy(int uid, int policy)247     public void removeUidPolicy(int uid, int policy) {
248         try {
249             mService.removeUidPolicy(uid, policy);
250         } catch (RemoteException e) {
251             throw e.rethrowFromSystemServer();
252         }
253     }
254 
255     /** @hide */
256     @UnsupportedAppUsage
getUidPolicy(int uid)257     public int getUidPolicy(int uid) {
258         try {
259             return mService.getUidPolicy(uid);
260         } catch (RemoteException e) {
261             throw e.rethrowFromSystemServer();
262         }
263     }
264 
265     /** @hide */
266     @UnsupportedAppUsage
getUidsWithPolicy(int policy)267     public int[] getUidsWithPolicy(int policy) {
268         try {
269             return mService.getUidsWithPolicy(policy);
270         } catch (RemoteException e) {
271             throw e.rethrowFromSystemServer();
272         }
273     }
274 
275     /** @hide */
276     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
registerListener(INetworkPolicyListener listener)277     public void registerListener(INetworkPolicyListener listener) {
278         try {
279             mService.registerListener(listener);
280         } catch (RemoteException e) {
281             throw e.rethrowFromSystemServer();
282         }
283     }
284 
285     /** @hide */
286     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
unregisterListener(INetworkPolicyListener listener)287     public void unregisterListener(INetworkPolicyListener listener) {
288         try {
289             mService.unregisterListener(listener);
290         } catch (RemoteException e) {
291             throw e.rethrowFromSystemServer();
292         }
293     }
294 
295     /** @hide */
296     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
registerSubscriptionCallback(@onNull SubscriptionCallback callback)297     public void registerSubscriptionCallback(@NonNull SubscriptionCallback callback) {
298         if (callback == null) {
299             throw new NullPointerException("Callback cannot be null.");
300         }
301 
302         final SubscriptionCallbackProxy callbackProxy = new SubscriptionCallbackProxy(callback);
303         if (null != mCallbackMap.putIfAbsent(callback, callbackProxy)) {
304             throw new IllegalArgumentException("Callback is already registered.");
305         }
306         registerListener(callbackProxy);
307     }
308 
309     /** @hide */
310     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
unregisterSubscriptionCallback(@onNull SubscriptionCallback callback)311     public void unregisterSubscriptionCallback(@NonNull SubscriptionCallback callback) {
312         if (callback == null) {
313             throw new NullPointerException("Callback cannot be null.");
314         }
315 
316         final SubscriptionCallbackProxy callbackProxy = mCallbackMap.remove(callback);
317         if (callbackProxy == null) return;
318 
319         unregisterListener(callbackProxy);
320     }
321 
322     /** @hide */
setNetworkPolicies(NetworkPolicy[] policies)323     public void setNetworkPolicies(NetworkPolicy[] policies) {
324         try {
325             mService.setNetworkPolicies(policies);
326         } catch (RemoteException e) {
327             throw e.rethrowFromSystemServer();
328         }
329     }
330 
331     /** @hide */
332     @UnsupportedAppUsage
getNetworkPolicies()333     public NetworkPolicy[] getNetworkPolicies() {
334         try {
335             return mService.getNetworkPolicies(mContext.getOpPackageName());
336         } catch (RemoteException e) {
337             throw e.rethrowFromSystemServer();
338         }
339     }
340 
341     /** @hide */
342     @UnsupportedAppUsage
setRestrictBackground(boolean restrictBackground)343     public void setRestrictBackground(boolean restrictBackground) {
344         try {
345             mService.setRestrictBackground(restrictBackground);
346         } catch (RemoteException e) {
347             throw e.rethrowFromSystemServer();
348         }
349     }
350 
351     /** @hide */
352     @UnsupportedAppUsage
getRestrictBackground()353     public boolean getRestrictBackground() {
354         try {
355             return mService.getRestrictBackground();
356         } catch (RemoteException e) {
357             throw e.rethrowFromSystemServer();
358         }
359     }
360 
361     /**
362      * Override connections to be temporarily marked as either unmetered or congested,
363      * along with automatic timeouts if desired.
364      *
365      * @param subId the subscriber ID this override applies to.
366      * @param overrideMask the bitmask that specifies which of the overrides is being
367      *            set or cleared.
368      * @param overrideValue the override values to set or clear.
369      * @param timeoutMillis the timeout after which the requested override will
370      *            be automatically cleared, or {@code 0} to leave in the
371      *            requested state until explicitly cleared, or the next reboot,
372      *            whichever happens first
373      * @param callingPackage the name of the package making the call.
374      * @hide
375      */
setSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask, @SubscriptionOverrideMask int overrideValue, long timeoutMillis, @NonNull String callingPackage)376     public void setSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
377             @SubscriptionOverrideMask int overrideValue, long timeoutMillis,
378                     @NonNull String callingPackage) {
379         try {
380             mService.setSubscriptionOverride(subId, overrideMask, overrideValue, timeoutMillis,
381                     callingPackage);
382         } catch (RemoteException e) {
383             throw e.rethrowFromSystemServer();
384         }
385     }
386 
387     /**
388      * Set the subscription plans for a specific subscriber.
389      *
390      * @param subId the subscriber this relationship applies to.
391      * @param plans the list of plans.
392      * @param callingPackage the name of the package making the call
393      * @hide
394      */
setSubscriptionPlans(int subId, @NonNull SubscriptionPlan[] plans, @NonNull String callingPackage)395     public void setSubscriptionPlans(int subId, @NonNull SubscriptionPlan[] plans,
396             @NonNull String callingPackage) {
397         try {
398             mService.setSubscriptionPlans(subId, plans, callingPackage);
399         } catch (RemoteException e) {
400             throw e.rethrowFromSystemServer();
401         }
402     }
403 
404     /**
405      * Get subscription plans for the given subscription id.
406      *
407      * @param subId the subscriber to get the subscription plans for.
408      * @param callingPackage the name of the package making the call.
409      * @hide
410      */
411     @NonNull
getSubscriptionPlans(int subId, @NonNull String callingPackage)412     public SubscriptionPlan[] getSubscriptionPlans(int subId, @NonNull String callingPackage) {
413         try {
414             return mService.getSubscriptionPlans(subId, callingPackage);
415         } catch (RemoteException e) {
416             throw e.rethrowFromSystemServer();
417         }
418     }
419 
420     /**
421      * Resets network policy settings back to factory defaults.
422      *
423      * @hide
424      */
factoryReset(String subscriber)425     public void factoryReset(String subscriber) {
426         try {
427             mService.factoryReset(subscriber);
428         } catch (RemoteException e) {
429             throw e.rethrowFromSystemServer();
430         }
431     }
432 
433     /** {@hide} */
434     @Deprecated
cycleIterator(NetworkPolicy policy)435     public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
436         final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
437         return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() {
438             @Override
439             public boolean hasNext() {
440                 return it.hasNext();
441             }
442 
443             @Override
444             public Pair<ZonedDateTime, ZonedDateTime> next() {
445                 if (hasNext()) {
446                     final Range<ZonedDateTime> r = it.next();
447                     return Pair.create(r.getLower(), r.getUpper());
448                 } else {
449                     return Pair.create(null, null);
450                 }
451             }
452         };
453     }
454 
455     /**
456      * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
457      * usually to protect critical system services.
458      * @hide
459      */
460     @Deprecated
461     public static boolean isUidValidForPolicy(Context context, int uid) {
462         // first, quick-reject non-applications
463         if (!UserHandle.isApp(uid)) {
464             return false;
465         }
466 
467         if (!ALLOW_PLATFORM_APP_POLICY) {
468             final PackageManager pm = context.getPackageManager();
469             final HashSet<Signature> systemSignature;
470             try {
471                 systemSignature = Sets.newHashSet(
472                         pm.getPackageInfo("android", GET_SIGNATURES).signatures);
473             } catch (NameNotFoundException e) {
474                 throw new RuntimeException("problem finding system signature", e);
475             }
476 
477             try {
478                 // reject apps signed with platform cert
479                 for (String packageName : pm.getPackagesForUid(uid)) {
480                     final HashSet<Signature> packageSignature = Sets.newHashSet(
481                             pm.getPackageInfo(packageName, GET_SIGNATURES).signatures);
482                     if (packageSignature.containsAll(systemSignature)) {
483                         return false;
484                     }
485                 }
486             } catch (NameNotFoundException e) {
487             }
488         }
489 
490         // nothing found above; we can apply policy to UID
491         return true;
492     }
493 
494     /**
495      * @hide
496      */
497     public static String uidRulesToString(int uidRules) {
498         final StringBuilder string = new StringBuilder().append(uidRules).append(" (");
499         if (uidRules == RULE_NONE) {
500             string.append("NONE");
501         } else {
502             string.append(DebugUtils.flagsToString(NetworkPolicyManager.class, "RULE_", uidRules));
503         }
504         string.append(")");
505         return string.toString();
506     }
507 
508     /**
509      * @hide
510      */
511     public static String uidPoliciesToString(int uidPolicies) {
512         final StringBuilder string = new StringBuilder().append(uidPolicies).append(" (");
513         if (uidPolicies == POLICY_NONE) {
514             string.append("NONE");
515         } else {
516             string.append(DebugUtils.flagsToString(NetworkPolicyManager.class,
517                     "POLICY_", uidPolicies));
518         }
519         string.append(")");
520         return string.toString();
521     }
522 
523     /**
524      * Returns true if {@param procState} is considered foreground and as such will be allowed
525      * to access network when the device is idle or in battery saver mode. Otherwise, false.
526      * @hide
527      */
528     public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) {
529         return procState <= FOREGROUND_THRESHOLD_STATE;
530     }
531 
532     /**
533      * Returns true if {@param procState} is considered foreground and as such will be allowed
534      * to access network when the device is in data saver mode. Otherwise, false.
535      * @hide
536      */
537     public static boolean isProcStateAllowedWhileOnRestrictBackground(int procState) {
538         return procState <= FOREGROUND_THRESHOLD_STATE;
539     }
540 
541     /** @hide */
542     public static String resolveNetworkId(WifiConfiguration config) {
543         return WifiInfo.sanitizeSsid(config.isPasspoint()
544                 ? config.providerFriendlyName : config.SSID);
545     }
546 
547     /** @hide */
548     public static String resolveNetworkId(String ssid) {
549         return WifiInfo.sanitizeSsid(ssid);
550     }
551 
552     /** @hide */
553     public static class SubscriptionCallback {
554         /**
555          * Notify clients of a new override about a given subscription.
556          *
557          * @param subId the subscriber this override applies to.
558          * @param overrideMask a bitmask that specifies which of the overrides is set.
559          * @param overrideValue a bitmask that specifies the override values.
560          */
561         public void onSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
562                 @SubscriptionOverrideMask int overrideValue) {}
563 
564         /**
565          * Notify of subscription plans change about a given subscription.
566          *
567          * @param subId the subscriber id that got subscription plans change.
568          * @param plans the list of subscription plans.
569          */
570         public void onSubscriptionPlansChanged(int subId, @NonNull SubscriptionPlan[] plans) {}
571     }
572 
573     /**
574      * SubscriptionCallback proxy for SubscriptionCallback object.
575      * @hide
576      */
577     public class SubscriptionCallbackProxy extends Listener {
578         private final SubscriptionCallback mCallback;
579 
580         SubscriptionCallbackProxy(SubscriptionCallback callback) {
581             mCallback = callback;
582         }
583 
584         @Override
585         public void onSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
586                 @SubscriptionOverrideMask int overrideValue) {
587             mCallback.onSubscriptionOverride(subId, overrideMask, overrideValue);
588         }
589 
590         @Override
591         public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) {
592             mCallback.onSubscriptionPlansChanged(subId, plans);
593         }
594     }
595 
596     /** {@hide} */
597     public static class Listener extends INetworkPolicyListener.Stub {
598         @Override public void onUidRulesChanged(int uid, int uidRules) { }
599         @Override public void onMeteredIfacesChanged(String[] meteredIfaces) { }
600         @Override public void onRestrictBackgroundChanged(boolean restrictBackground) { }
601         @Override public void onUidPoliciesChanged(int uid, int uidPolicies) { }
602         @Override public void onSubscriptionOverride(int subId, int overrideMask,
603                 int overrideValue) { }
604         @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { }
605     }
606 }
607