• 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.app.ActivityManager.procStateToString;
20 import static android.content.pm.PackageManager.GET_SIGNATURES;
21 
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.RequiresPermission;
26 import android.annotation.SystemApi;
27 import android.annotation.SystemService;
28 import android.annotation.TestApi;
29 import android.app.ActivityManager;
30 import android.app.ActivityManager.ProcessCapability;
31 import android.compat.annotation.UnsupportedAppUsage;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.pm.PackageManager;
35 import android.content.pm.PackageManager.NameNotFoundException;
36 import android.content.pm.Signature;
37 import android.net.wifi.WifiConfiguration;
38 import android.net.wifi.WifiInfo;
39 import android.os.Build;
40 import android.os.Process;
41 import android.os.RemoteException;
42 import android.telephony.Annotation;
43 import android.telephony.SubscriptionPlan;
44 import android.util.DebugUtils;
45 import android.util.Pair;
46 import android.util.Range;
47 
48 import com.android.internal.util.function.pooled.PooledLambda;
49 
50 import com.google.android.collect.Sets;
51 
52 import java.lang.annotation.Retention;
53 import java.lang.annotation.RetentionPolicy;
54 import java.time.ZonedDateTime;
55 import java.util.HashSet;
56 import java.util.Iterator;
57 import java.util.Map;
58 import java.util.concurrent.ConcurrentHashMap;
59 import java.util.concurrent.Executor;
60 
61 /**
62  * Manager for creating and modifying network policy rules.
63  *
64  * @hide
65  */
66 @TestApi
67 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
68 @SystemService(Context.NETWORK_POLICY_SERVICE)
69 public class NetworkPolicyManager {
70 
71     /* POLICY_* are masks and can be ORed, although currently they are not.*/
72     /**
73      * No specific network policy, use system default.
74      * @hide
75      */
76     public static final int POLICY_NONE = 0x0;
77     /**
78      * Reject network usage on metered networks when application in background.
79      * @hide
80      */
81     public static final int POLICY_REJECT_METERED_BACKGROUND = 0x1;
82     /**
83      * Allow metered network use in the background even when in data usage save mode.
84      * @hide
85      */
86     public static final int POLICY_ALLOW_METERED_BACKGROUND = 0x4;
87 
88     /*
89      * Rules defining whether an uid has access to a network given its type (metered / non-metered).
90      *
91      * These rules are bits and can be used in bitmask operations; in particular:
92      * - rule & RULE_MASK_METERED: returns the metered-networks status.
93      * - rule & RULE_MASK_ALL: returns the all-networks status.
94      *
95      * The RULE_xxx_ALL rules applies to all networks (metered or non-metered), but on
96      * metered networks, the RULE_xxx_METERED rules should be checked first. For example,
97      * if the device is on Battery Saver Mode and Data Saver Mode simulatenously, and a uid
98      * is allowlisted for the former but not the latter, its status would be
99      * RULE_REJECT_METERED | RULE_ALLOW_ALL, meaning it could have access to non-metered
100      * networks but not to metered networks.
101      *
102      * See network-policy-restrictions.md for more info.
103      */
104 
105     /**
106      * No specific rule was set
107      * @hide
108      */
109     public static final int RULE_NONE = 0;
110     /**
111      * Allow traffic on metered networks.
112      * @hide
113      */
114     public static final int RULE_ALLOW_METERED = 1 << 0;
115     /**
116      * Temporarily allow traffic on metered networks because app is on foreground.
117      * @hide
118      */
119     public static final int RULE_TEMPORARY_ALLOW_METERED = 1 << 1;
120     /**
121      * Reject traffic on metered networks.
122      * @hide
123      */
124     public static final int RULE_REJECT_METERED = 1 << 2;
125     /**
126      * Network traffic should be allowed on all networks (metered or non-metered), although
127      * metered-network restrictions could still apply.
128      * @hide
129      */
130     public static final int RULE_ALLOW_ALL = 1 << 5;
131     /**
132      * Reject traffic on all networks.
133      * @hide
134      */
135     public static final int RULE_REJECT_ALL = 1 << 6;
136     /**
137      * Reject traffic on all networks for restricted networking mode.
138      * @hide
139      */
140     public static final int RULE_REJECT_RESTRICTED_MODE = 1 << 10;
141 
142     /**
143      * Mask used to get the {@code RULE_xxx_METERED} rules
144      * @hide
145      */
146     public static final int MASK_METERED_NETWORKS = 0b000000001111;
147     /**
148      * Mask used to get the {@code RULE_xxx_ALL} rules
149      * @hide
150      */
151     public static final int MASK_ALL_NETWORKS     = 0b000011110000;
152     /**
153      * Mask used to get the {@code RULE_xxx_RESTRICTED_MODE} rules
154      * @hide
155      */
156     public static final int MASK_RESTRICTED_MODE_NETWORKS     = 0b111100000000;
157 
158     /** @hide */
159     public static final int FIREWALL_RULE_DEFAULT = 0;
160     /** @hide */
161     public static final String FIREWALL_CHAIN_NAME_NONE = "none";
162     /** @hide */
163     public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable";
164     /** @hide */
165     public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
166     /** @hide */
167     public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave";
168     /** @hide */
169     public static final String FIREWALL_CHAIN_NAME_RESTRICTED = "restricted";
170 
171     private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
172 
173     /** @hide */
174     public static final int FOREGROUND_THRESHOLD_STATE =
175             ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
176 
177     /**
178      * {@link Intent} extra that indicates which {@link NetworkTemplate} rule it
179      * applies to.
180      * @hide
181      */
182     public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
183 
184     /**
185      * Mask used to check if an override value is marked as unmetered.
186      * @hide
187      */
188     public static final int SUBSCRIPTION_OVERRIDE_UNMETERED = 1 << 0;
189 
190     /**
191      * Mask used to check if an override value is marked as congested.
192      * @hide
193      */
194     public static final int SUBSCRIPTION_OVERRIDE_CONGESTED = 1 << 1;
195 
196     /**
197      * @hide
198      */
199     @Retention(RetentionPolicy.SOURCE)
200     @IntDef(flag = true, prefix = { "SUBSCRIPTION_OVERRIDE_" }, value = {
201         SUBSCRIPTION_OVERRIDE_UNMETERED,
202         SUBSCRIPTION_OVERRIDE_CONGESTED
203     })
204     public @interface SubscriptionOverrideMask {}
205 
206     /**
207      * Flag to indicate that app is not exempt from any network restrictions.
208      *
209      * @hide
210      */
211     public static final int ALLOWED_REASON_NONE = 0;
212     /**
213      * Flag to indicate that app is exempt from certain network restrictions because of it being a
214      * system component.
215      *
216      * @hide
217      */
218     public static final int ALLOWED_REASON_SYSTEM = 1 << 0;
219     /**
220      * Flag to indicate that app is exempt from certain network restrictions because of it being
221      * in the foreground.
222      *
223      * @hide
224      */
225     public static final int ALLOWED_REASON_FOREGROUND = 1 << 1;
226     /**
227      * Flag to indicate that app is exempt from certain network restrictions because of it being
228      * in the {@code allow-in-power-save} list.
229      *
230      * @hide
231      */
232     public static final int ALLOWED_REASON_POWER_SAVE_ALLOWLIST = 1 << 2;
233     /**
234      * Flag to indicate that app is exempt from certain network restrictions because of it being
235      * in the {@code allow-in-power-save-except-idle} list.
236      *
237      * @hide
238      */
239     public static final int ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST = 1 << 3;
240     /**
241      * Flag to indicate that app is exempt from certain network restrictions because of it holding
242      * certain privileged permissions.
243      *
244      * @hide
245      */
246     public static final int ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS = 1 << 4;
247     /**
248      * Flag to indicate that app is exempt from certain metered network restrictions because user
249      * explicitly exempted it.
250      *
251      * @hide
252      */
253     public static final int ALLOWED_METERED_REASON_USER_EXEMPTED = 1 << 16;
254     /**
255      * Flag to indicate that app is exempt from certain metered network restrictions because of it
256      * being a system component.
257      *
258      * @hide
259      */
260     public static final int ALLOWED_METERED_REASON_SYSTEM = 1 << 17;
261     /**
262      * Flag to indicate that app is exempt from certain metered network restrictions because of it
263      * being in the foreground.
264      *
265      * @hide
266      */
267     public static final int ALLOWED_METERED_REASON_FOREGROUND = 1 << 18;
268 
269     /** @hide */
270     public static final int ALLOWED_METERED_REASON_MASK = 0xffff0000;
271 
272     private final Context mContext;
273     @UnsupportedAppUsage
274     private INetworkPolicyManager mService;
275 
276     private final Map<SubscriptionCallback, SubscriptionCallbackProxy>
277             mSubscriptionCallbackMap = new ConcurrentHashMap<>();
278     private final Map<NetworkPolicyCallback, NetworkPolicyCallbackProxy>
279             mNetworkPolicyCallbackMap = new ConcurrentHashMap<>();
280 
281     /** @hide */
NetworkPolicyManager(Context context, INetworkPolicyManager service)282     public NetworkPolicyManager(Context context, INetworkPolicyManager service) {
283         if (service == null) {
284             throw new IllegalArgumentException("missing INetworkPolicyManager");
285         }
286         mContext = context;
287         mService = service;
288     }
289 
290     /** @hide */
291     @UnsupportedAppUsage
from(Context context)292     public static NetworkPolicyManager from(Context context) {
293         return (NetworkPolicyManager) context.getSystemService(Context.NETWORK_POLICY_SERVICE);
294     }
295 
296     /**
297      * Set policy flags for specific UID.
298      *
299      * @param policy should be {@link #POLICY_NONE} or any combination of {@code POLICY_} flags,
300      *     although it is not validated.
301      * @hide
302      */
303     @UnsupportedAppUsage
setUidPolicy(int uid, int policy)304     public void setUidPolicy(int uid, int policy) {
305         try {
306             mService.setUidPolicy(uid, policy);
307         } catch (RemoteException e) {
308             throw e.rethrowFromSystemServer();
309         }
310     }
311 
312     /**
313      * Add policy flags for specific UID.
314      *
315      * <p>The given policy bits will be set for the uid.
316      *
317      * @param policy should be {@link #POLICY_NONE} or any combination of {@code POLICY_} flags,
318      *     although it is not validated.
319      * @hide
320      */
addUidPolicy(int uid, int policy)321     public void addUidPolicy(int uid, int policy) {
322         try {
323             mService.addUidPolicy(uid, policy);
324         } catch (RemoteException e) {
325             throw e.rethrowFromSystemServer();
326         }
327     }
328 
329     /**
330      * Clear/remove policy flags for specific UID.
331      *
332      * <p>The given policy bits will be set for the uid.
333      *
334      * @param policy should be {@link #POLICY_NONE} or any combination of {@code POLICY_} flags,
335      *     although it is not validated.
336      * @hide
337      */
removeUidPolicy(int uid, int policy)338     public void removeUidPolicy(int uid, int policy) {
339         try {
340             mService.removeUidPolicy(uid, policy);
341         } catch (RemoteException e) {
342             throw e.rethrowFromSystemServer();
343         }
344     }
345 
346     /** @hide */
347     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getUidPolicy(int uid)348     public int getUidPolicy(int uid) {
349         try {
350             return mService.getUidPolicy(uid);
351         } catch (RemoteException e) {
352             throw e.rethrowFromSystemServer();
353         }
354     }
355 
356     /** @hide */
357     @UnsupportedAppUsage
getUidsWithPolicy(int policy)358     public int[] getUidsWithPolicy(int policy) {
359         try {
360             return mService.getUidsWithPolicy(policy);
361         } catch (RemoteException e) {
362             throw e.rethrowFromSystemServer();
363         }
364     }
365 
366     /** @hide */
367     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
registerListener(INetworkPolicyListener listener)368     public void registerListener(INetworkPolicyListener listener) {
369         try {
370             mService.registerListener(listener);
371         } catch (RemoteException e) {
372             throw e.rethrowFromSystemServer();
373         }
374     }
375 
376     /** @hide */
377     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
unregisterListener(INetworkPolicyListener listener)378     public void unregisterListener(INetworkPolicyListener listener) {
379         try {
380             mService.unregisterListener(listener);
381         } catch (RemoteException e) {
382             throw e.rethrowFromSystemServer();
383         }
384     }
385 
386     /** @hide */
387     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
registerSubscriptionCallback(@onNull SubscriptionCallback callback)388     public void registerSubscriptionCallback(@NonNull SubscriptionCallback callback) {
389         if (callback == null) {
390             throw new NullPointerException("Callback cannot be null.");
391         }
392 
393         final SubscriptionCallbackProxy callbackProxy = new SubscriptionCallbackProxy(callback);
394         if (null != mSubscriptionCallbackMap.putIfAbsent(callback, callbackProxy)) {
395             throw new IllegalArgumentException("Callback is already registered.");
396         }
397         registerListener(callbackProxy);
398     }
399 
400     /** @hide */
401     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
unregisterSubscriptionCallback(@onNull SubscriptionCallback callback)402     public void unregisterSubscriptionCallback(@NonNull SubscriptionCallback callback) {
403         if (callback == null) {
404             throw new NullPointerException("Callback cannot be null.");
405         }
406 
407         final SubscriptionCallbackProxy callbackProxy = mSubscriptionCallbackMap.remove(callback);
408         if (callbackProxy == null) return;
409 
410         unregisterListener(callbackProxy);
411     }
412 
413     /** @hide */
setNetworkPolicies(NetworkPolicy[] policies)414     public void setNetworkPolicies(NetworkPolicy[] policies) {
415         try {
416             mService.setNetworkPolicies(policies);
417         } catch (RemoteException e) {
418             throw e.rethrowFromSystemServer();
419         }
420     }
421 
422     /** @hide */
423     @UnsupportedAppUsage
getNetworkPolicies()424     public NetworkPolicy[] getNetworkPolicies() {
425         try {
426             return mService.getNetworkPolicies(mContext.getOpPackageName());
427         } catch (RemoteException e) {
428             throw e.rethrowFromSystemServer();
429         }
430     }
431 
432     /** @hide */
433     @TestApi
434     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
setRestrictBackground(boolean restrictBackground)435     public void setRestrictBackground(boolean restrictBackground) {
436         try {
437             mService.setRestrictBackground(restrictBackground);
438         } catch (RemoteException e) {
439             throw e.rethrowFromSystemServer();
440         }
441     }
442 
443     /** @hide */
444     @TestApi
445     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getRestrictBackground()446     public boolean getRestrictBackground() {
447         try {
448             return mService.getRestrictBackground();
449         } catch (RemoteException e) {
450             throw e.rethrowFromSystemServer();
451         }
452     }
453 
454     /**
455      * Determines if an UID is subject to metered network restrictions while running in background.
456      *
457      * @param uid The UID whose status needs to be checked.
458      * @return {@link ConnectivityManager#RESTRICT_BACKGROUND_STATUS_DISABLED},
459      *         {@link ConnectivityManager##RESTRICT_BACKGROUND_STATUS_ENABLED},
460      *         or {@link ConnectivityManager##RESTRICT_BACKGROUND_STATUS_WHITELISTED} to denote
461      *         the current status of the UID.
462      * @hide
463      */
464     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
465     @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
getRestrictBackgroundStatus(int uid)466     public int getRestrictBackgroundStatus(int uid) {
467         try {
468             return mService.getRestrictBackgroundStatus(uid);
469         } catch (RemoteException e) {
470             throw e.rethrowFromSystemServer();
471         }
472     }
473 
474     /**
475      * Override connections to be temporarily marked as either unmetered or congested,
476      * along with automatic timeouts if desired.
477      *
478      * @param subId the subscriber ID this override applies to.
479      * @param overrideMask the bitmask that specifies which of the overrides is being
480      *            set or cleared.
481      * @param overrideValue the override values to set or clear.
482      * @param networkTypes the network types this override applies to. If no
483      *            network types are specified, override values will be ignored.
484      *            {@see TelephonyManager#getAllNetworkTypes()}
485      * @param timeoutMillis the timeout after which the requested override will
486      *            be automatically cleared, or {@code 0} to leave in the
487      *            requested state until explicitly cleared, or the next reboot,
488      *            whichever happens first
489      * @param callingPackage the name of the package making the call.
490      * @hide
491      */
setSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask, @SubscriptionOverrideMask int overrideValue, @NonNull @Annotation.NetworkType int[] networkTypes, long timeoutMillis, @NonNull String callingPackage)492     public void setSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
493             @SubscriptionOverrideMask int overrideValue,
494             @NonNull @Annotation.NetworkType int[] networkTypes, long timeoutMillis,
495             @NonNull String callingPackage) {
496         try {
497             mService.setSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes,
498                     timeoutMillis, callingPackage);
499         } catch (RemoteException e) {
500             throw e.rethrowFromSystemServer();
501         }
502     }
503 
504     /**
505      * Set the subscription plans for a specific subscriber.
506      *
507      * @param subId the subscriber this relationship applies to.
508      * @param plans the list of plans.
509      * @param callingPackage the name of the package making the call
510      * @hide
511      */
setSubscriptionPlans(int subId, @NonNull SubscriptionPlan[] plans, @NonNull String callingPackage)512     public void setSubscriptionPlans(int subId, @NonNull SubscriptionPlan[] plans,
513             @NonNull String callingPackage) {
514         try {
515             mService.setSubscriptionPlans(subId, plans, callingPackage);
516         } catch (RemoteException e) {
517             throw e.rethrowFromSystemServer();
518         }
519     }
520 
521     /**
522      * Get subscription plans for the given subscription id.
523      *
524      * @param subId the subscriber to get the subscription plans for.
525      * @param callingPackage the name of the package making the call.
526      * @hide
527      */
528     @NonNull
getSubscriptionPlans(int subId, @NonNull String callingPackage)529     public SubscriptionPlan[] getSubscriptionPlans(int subId, @NonNull String callingPackage) {
530         try {
531             return mService.getSubscriptionPlans(subId, callingPackage);
532         } catch (RemoteException e) {
533             throw e.rethrowFromSystemServer();
534         }
535     }
536 
537     /**
538      * Resets network policy settings back to factory defaults.
539      *
540      * @hide
541      */
factoryReset(String subscriber)542     public void factoryReset(String subscriber) {
543         try {
544             mService.factoryReset(subscriber);
545         } catch (RemoteException e) {
546             throw e.rethrowFromSystemServer();
547         }
548     }
549 
550     /**
551      * Check that networking is blocked for the given uid.
552      *
553      * @param uid The target uid.
554      * @param meteredNetwork True if the network is metered.
555      * @return true if networking is blocked for the given uid according to current networking
556      *         policies.
557      */
558     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
isUidNetworkingBlocked(int uid, boolean meteredNetwork)559     public boolean isUidNetworkingBlocked(int uid, boolean meteredNetwork) {
560         try {
561             return mService.isUidNetworkingBlocked(uid, meteredNetwork);
562         } catch (RemoteException e) {
563             throw e.rethrowFromSystemServer();
564         }
565     }
566 
567     /**
568      * Check that the given uid is restricted from doing networking on metered networks.
569      *
570      * @param uid The target uid.
571      * @return true if the given uid is restricted from doing networking on metered networks.
572      */
573     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
isUidRestrictedOnMeteredNetworks(int uid)574     public boolean isUidRestrictedOnMeteredNetworks(int uid) {
575         try {
576             return mService.isUidRestrictedOnMeteredNetworks(uid);
577         } catch (RemoteException e) {
578             throw e.rethrowFromSystemServer();
579         }
580     }
581 
582     /**
583      * Gets a hint on whether it is desirable to use multipath data transfer on the given network.
584      *
585      * @return One of the ConnectivityManager.MULTIPATH_PREFERENCE_* constants.
586      *
587      * @hide
588      */
589     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
590     @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
getMultipathPreference(@onNull Network network)591     public int getMultipathPreference(@NonNull Network network) {
592         try {
593             return mService.getMultipathPreference(network);
594         } catch (RemoteException e) {
595             throw e.rethrowFromSystemServer();
596         }
597     }
598 
599     /** {@hide} */
600     @Deprecated
cycleIterator(NetworkPolicy policy)601     public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
602         final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
603         return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() {
604             @Override
605             public boolean hasNext() {
606                 return it.hasNext();
607             }
608 
609             @Override
610             public Pair<ZonedDateTime, ZonedDateTime> next() {
611                 if (hasNext()) {
612                     final Range<ZonedDateTime> r = it.next();
613                     return Pair.create(r.getLower(), r.getUpper());
614                 } else {
615                     return Pair.create(null, null);
616                 }
617             }
618         };
619     }
620 
621     /**
622      * Check if given UID can have a {@link #setUidPolicy(int, int)} defined,
623      * usually to protect critical system services.
624      * @hide
625      */
626     @Deprecated
627     public static boolean isUidValidForPolicy(Context context, int uid) {
628         // first, quick-reject non-applications
629         if (!Process.isApplicationUid(uid)) {
630             return false;
631         }
632 
633         if (!ALLOW_PLATFORM_APP_POLICY) {
634             final PackageManager pm = context.getPackageManager();
635             final HashSet<Signature> systemSignature;
636             try {
637                 systemSignature = Sets.newHashSet(
638                         pm.getPackageInfo("android", GET_SIGNATURES).signatures);
639             } catch (NameNotFoundException e) {
640                 throw new RuntimeException("problem finding system signature", e);
641             }
642 
643             try {
644                 // reject apps signed with platform cert
645                 for (String packageName : pm.getPackagesForUid(uid)) {
646                     final HashSet<Signature> packageSignature = Sets.newHashSet(
647                             pm.getPackageInfo(packageName, GET_SIGNATURES).signatures);
648                     if (packageSignature.containsAll(systemSignature)) {
649                         return false;
650                     }
651                 }
652             } catch (NameNotFoundException e) {
653             }
654         }
655 
656         // nothing found above; we can apply policy to UID
657         return true;
658     }
659 
660     /**
661      * @hide
662      */
663     public static String uidRulesToString(int uidRules) {
664         final StringBuilder string = new StringBuilder().append(uidRules).append(" (");
665         if (uidRules == RULE_NONE) {
666             string.append("NONE");
667         } else {
668             string.append(DebugUtils.flagsToString(NetworkPolicyManager.class, "RULE_", uidRules));
669         }
670         string.append(")");
671         return string.toString();
672     }
673 
674     /**
675      * @hide
676      */
677     public static String uidPoliciesToString(int uidPolicies) {
678         final StringBuilder string = new StringBuilder().append(uidPolicies).append(" (");
679         if (uidPolicies == POLICY_NONE) {
680             string.append("NONE");
681         } else {
682             string.append(DebugUtils.flagsToString(NetworkPolicyManager.class,
683                     "POLICY_", uidPolicies));
684         }
685         string.append(")");
686         return string.toString();
687     }
688 
689     /**
690      * Returns true if {@param procState} is considered foreground and as such will be allowed
691      * to access network when the device is idle or in battery saver mode. Otherwise, false.
692      * @hide
693      */
694     public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(@Nullable UidState uidState) {
695         if (uidState == null) {
696             return false;
697         }
698         return isProcStateAllowedWhileIdleOrPowerSaveMode(uidState.procState, uidState.capability);
699     }
700 
701     /** @hide */
702     public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(
703             int procState, @ProcessCapability int capability) {
704         return procState <= FOREGROUND_THRESHOLD_STATE
705                 || (capability & ActivityManager.PROCESS_CAPABILITY_NETWORK) != 0;
706     }
707 
708     /**
709      * Returns true if {@param procState} is considered foreground and as such will be allowed
710      * to access network when the device is in data saver mode. Otherwise, false.
711      * @hide
712      */
713     public static boolean isProcStateAllowedWhileOnRestrictBackground(@Nullable UidState uidState) {
714         if (uidState == null) {
715             return false;
716         }
717         return isProcStateAllowedWhileOnRestrictBackground(uidState.procState);
718     }
719 
720     /** @hide */
721     public static boolean isProcStateAllowedWhileOnRestrictBackground(int procState) {
722         // Data saver and bg policy restrictions will only take procstate into account.
723         return procState <= FOREGROUND_THRESHOLD_STATE;
724     }
725 
726     /** @hide */
727     public static final class UidState {
728         public int uid;
729         public int procState;
730         public int capability;
731 
732         public UidState(int uid, int procState, int capability) {
733             this.uid = uid;
734             this.procState = procState;
735             this.capability = capability;
736         }
737 
738         @Override
739         public String toString() {
740             final StringBuilder sb = new StringBuilder();
741             sb.append("{procState=");
742             sb.append(procStateToString(procState));
743             sb.append(",cap=");
744             ActivityManager.printCapabilitiesSummary(sb, capability);
745             sb.append("}");
746             return sb.toString();
747         }
748     }
749 
750     /** @hide */
751     @TestApi
752     @NonNull
753     public static String resolveNetworkId(@NonNull WifiConfiguration config) {
754         return WifiInfo.sanitizeSsid(config.isPasspoint()
755                 ? config.providerFriendlyName : config.SSID);
756     }
757 
758     /** @hide */
759     public static String resolveNetworkId(String ssid) {
760         return WifiInfo.sanitizeSsid(ssid);
761     }
762 
763     /**
764      * Returns the {@code string} representation of {@code blockedReasons} argument.
765      *
766      * @param blockedReasons Value indicating the reasons for why the network access of an UID is
767      *                       blocked.
768      * @hide
769      */
770     @NonNull
771     public static String blockedReasonsToString(int blockedReasons) {
772         return DebugUtils.flagsToString(ConnectivityManager.class, "BLOCKED_", blockedReasons);
773     }
774 
775     /** @hide */
776     @NonNull
777     public static String allowedReasonsToString(int allowedReasons) {
778         return DebugUtils.flagsToString(NetworkPolicyManager.class, "ALLOWED_", allowedReasons);
779     }
780 
781     /**
782      * Register a {@link NetworkPolicyCallback} to listen for changes to network blocked status
783      * of apps.
784      *
785      * Note that when a caller tries to register a new callback, it might replace a previously
786      * registered callback if it is considered equal to the new one, based on the
787      * {@link Object#equals(Object)} check.
788      *
789      * @param executor The {@link Executor} to run the callback on.
790      * @param callback The {@link NetworkPolicyCallback} to be registered.
791      * @hide
792      */
793     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
794     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
795     public void registerNetworkPolicyCallback(@Nullable Executor executor,
796             @NonNull NetworkPolicyCallback callback) {
797         if (callback == null) {
798             throw new NullPointerException("Callback cannot be null.");
799         }
800 
801         final NetworkPolicyCallbackProxy callbackProxy = new NetworkPolicyCallbackProxy(
802                 executor, callback);
803         registerListener(callbackProxy);
804         mNetworkPolicyCallbackMap.put(callback, callbackProxy);
805     }
806 
807     /**
808      * Unregister a previously registered {@link NetworkPolicyCallback}.
809      *
810      * @param callback The {@link NetworkPolicyCallback} to be unregistered.
811      * @hide
812      */
813     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
814     @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY)
815     public void unregisterNetworkPolicyCallback(@NonNull NetworkPolicyCallback callback) {
816         if (callback == null) {
817             throw new NullPointerException("Callback cannot be null.");
818         }
819 
820         final NetworkPolicyCallbackProxy callbackProxy = mNetworkPolicyCallbackMap.remove(callback);
821         if (callbackProxy == null) return;
822         unregisterListener(callbackProxy);
823     }
824 
825     /**
826      * Interface for the callback to listen for changes to network blocked status of apps.
827      *
828      * @hide
829      */
830     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
831     public interface NetworkPolicyCallback {
832         /**
833          * Called when the reason for why the network access of an UID is blocked changes.
834          *
835          * @param uid The UID for which the blocked status changed.
836          * @param blockedReasons Value indicating the reasons for why the network access of an
837          *                       UID is blocked.
838          * @hide
839          */
840         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
841         default void onUidBlockedReasonChanged(int uid, int blockedReasons) {}
842     }
843 
844     /** @hide */
845     public static class NetworkPolicyCallbackProxy extends Listener {
846         private final Executor mExecutor;
847         private final NetworkPolicyCallback mCallback;
848 
849         NetworkPolicyCallbackProxy(@Nullable Executor executor,
850                 @NonNull NetworkPolicyCallback callback) {
851             mExecutor = executor;
852             mCallback = callback;
853         }
854 
855         @Override
856         public void onBlockedReasonChanged(int uid, int oldBlockedReasons, int newBlockedReasons) {
857             if (oldBlockedReasons != newBlockedReasons) {
858                 dispatchOnUidBlockedReasonChanged(mExecutor, mCallback, uid, newBlockedReasons);
859             }
860         }
861     }
862 
863     private static void dispatchOnUidBlockedReasonChanged(@Nullable Executor executor,
864             @NonNull NetworkPolicyCallback callback, int uid, int blockedReasons) {
865         if (executor == null) {
866             callback.onUidBlockedReasonChanged(uid, blockedReasons);
867         } else {
868             executor.execute(PooledLambda.obtainRunnable(
869                     NetworkPolicyCallback::onUidBlockedReasonChanged,
870                     callback, uid, blockedReasons).recycleOnUse());
871         }
872     }
873 
874     /** @hide */
875     public static class SubscriptionCallback {
876         /**
877          * Notify clients of a new override about a given subscription.
878          *
879          * @param subId the subscriber this override applies to.
880          * @param overrideMask a bitmask that specifies which of the overrides is set.
881          * @param overrideValue a bitmask that specifies the override values.
882          * @param networkTypes the network types this override applies to.
883          */
884         public void onSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
885                 @SubscriptionOverrideMask int overrideValue, int[] networkTypes) {}
886 
887         /**
888          * Notify of subscription plans change about a given subscription.
889          *
890          * @param subId the subscriber id that got subscription plans change.
891          * @param plans the list of subscription plans.
892          */
893         public void onSubscriptionPlansChanged(int subId, @NonNull SubscriptionPlan[] plans) {}
894     }
895 
896     /**
897      * SubscriptionCallback proxy for SubscriptionCallback object.
898      * @hide
899      */
900     public class SubscriptionCallbackProxy extends Listener {
901         private final SubscriptionCallback mCallback;
902 
903         SubscriptionCallbackProxy(SubscriptionCallback callback) {
904             mCallback = callback;
905         }
906 
907         @Override
908         public void onSubscriptionOverride(int subId, @SubscriptionOverrideMask int overrideMask,
909                 @SubscriptionOverrideMask int overrideValue, int[] networkTypes) {
910             mCallback.onSubscriptionOverride(subId, overrideMask, overrideValue, networkTypes);
911         }
912 
913         @Override
914         public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) {
915             mCallback.onSubscriptionPlansChanged(subId, plans);
916         }
917     }
918 
919     /** {@hide} */
920     public static class Listener extends INetworkPolicyListener.Stub {
921         @Override public void onUidRulesChanged(int uid, int uidRules) { }
922         @Override public void onMeteredIfacesChanged(String[] meteredIfaces) { }
923         @Override public void onRestrictBackgroundChanged(boolean restrictBackground) { }
924         @Override public void onUidPoliciesChanged(int uid, int uidPolicies) { }
925         @Override public void onSubscriptionOverride(int subId, int overrideMask,
926                 int overrideValue, int[] networkTypes) { }
927         @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { }
928         @Override public void onBlockedReasonChanged(int uid,
929                 int oldBlockedReasons, int newBlockedReasons) { }
930     }
931 }
932