2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server;
19 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
20 import static android.Manifest.permission.NETWORK_SETTINGS;
21 import static android.Manifest.permission.NETWORK_STACK;
22 import static android.Manifest.permission.SHUTDOWN;
23 import static android.net.INetd.FIREWALL_BLACKLIST;
24 import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
25 import static android.net.INetd.FIREWALL_CHAIN_NONE;
26 import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
27 import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
28 import static android.net.INetd.FIREWALL_RULE_ALLOW;
29 import static android.net.INetd.FIREWALL_RULE_DENY;
30 import static android.net.INetd.FIREWALL_WHITELIST;
31 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
32 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
33 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
34 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
35 import static android.net.NetworkStats.SET_DEFAULT;
36 import static android.net.NetworkStats.STATS_PER_UID;
37 import static android.net.NetworkStats.TAG_ALL;
38 import static android.net.NetworkStats.TAG_NONE;
39 import static android.net.TrafficStats.UID_TETHERING;
41 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
43 import android.annotation.NonNull;
44 import android.app.ActivityManager;
45 import android.content.Context;
46 import android.net.ConnectivityManager;
47 import android.net.INetd;
48 import android.net.INetdUnsolicitedEventListener;
49 import android.net.INetworkManagementEventObserver;
50 import android.net.ITetheringStatsProvider;
51 import android.net.InetAddresses;
52 import android.net.InterfaceConfiguration;
53 import android.net.InterfaceConfigurationParcel;
54 import android.net.IpPrefix;
55 import android.net.LinkAddress;
56 import android.net.Network;
57 import android.net.NetworkPolicyManager;
58 import android.net.NetworkStats;
59 import android.net.NetworkUtils;
60 import android.net.RouteInfo;
61 import android.net.TetherStatsParcel;
62 import android.net.UidRange;
63 import android.net.UidRangeParcel;
64 import android.net.util.NetdService;
65 import android.os.BatteryStats;
66 import android.os.Binder;
67 import android.os.Handler;
68 import android.os.IBinder;
69 import android.os.INetworkActivityListener;
70 import android.os.INetworkManagementService;
71 import android.os.Process;
72 import android.os.RemoteCallbackList;
73 import android.os.RemoteException;
74 import android.os.ServiceManager;
75 import android.os.ServiceSpecificException;
76 import android.os.StrictMode;
77 import android.os.SystemClock;
78 import android.os.SystemProperties;
79 import android.os.Trace;
80 import android.telephony.DataConnectionRealTimeInfo;
81 import android.text.TextUtils;
82 import android.util.Log;
83 import android.util.Slog;
84 import android.util.SparseBooleanArray;
85 import android.util.SparseIntArray;
86 import android.util.StatsLog;
88 import com.android.internal.annotations.GuardedBy;
89 import com.android.internal.annotations.VisibleForTesting;
90 import com.android.internal.app.IBatteryStats;
91 import com.android.internal.util.DumpUtils;
92 import com.android.internal.util.HexDump;
93 import com.android.internal.util.Preconditions;
94 import com.android.server.net.NetworkStatsFactory;
96 import com.google.android.collect.Maps;
98 import java.io.BufferedReader;
99 import java.io.DataInputStream;
100 import java.io.FileDescriptor;
101 import java.io.FileInputStream;
102 import java.io.IOException;
103 import java.io.InputStreamReader;
104 import java.io.PrintWriter;
105 import java.net.InetAddress;
106 import java.net.InterfaceAddress;
107 import java.util.ArrayList;
108 import java.util.Arrays;
109 import java.util.HashMap;
110 import java.util.List;
111 import java.util.Map;
116 public class NetworkManagementService extends INetworkManagementService.Stub {
119 * Helper class that encapsulates NetworkManagementService dependencies and makes them
120 * easier to mock in unit tests.
122 static class SystemServices {
123 public IBinder getService(String name) {
124 return ServiceManager.getService(name);
126 public void registerLocalService(NetworkManagementInternal nmi) {
127 LocalServices.addService(NetworkManagementInternal.class, nmi);
129 public INetd getNetd() {
130 return NetdService.get();
134 private static final String TAG = "NetworkManagement";
135 private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
137 private static final int MAX_UID_RANGES_PER_COMMAND = 10;
140 * Name representing {@link #setGlobalAlert(long)} limit when delivered to
141 * {@link INetworkManagementEventObserver#limitReached(String, String)}.
143 public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
145 static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
147 static final boolean MODIFY_OPERATION_ADD = true;
148 static final boolean MODIFY_OPERATION_REMOVE = false;
151 * Binder context for this service
153 private final Context mContext;
155 private final Handler mDaemonHandler;
157 private final SystemServices mServices;
159 private INetd mNetdService;
161 private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener;
163 private IBatteryStats mBatteryStats;
165 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
166 new RemoteCallbackList<>();
168 private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
170 @GuardedBy("mTetheringStatsProviders")
171 private final HashMap<ITetheringStatsProvider, String>
172 mTetheringStatsProviders = Maps.newHashMap();
175 * If both locks need to be held, then they should be obtained in the order:
176 * first {@link #mQuotaLock} and then {@link #mRulesLock}.
178 private final Object mQuotaLock = new Object();
179 private final Object mRulesLock = new Object();
181 /** Set of interfaces with active quotas. */
182 @GuardedBy("mQuotaLock")
183 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap();
184 /** Set of interfaces with active alerts. */
185 @GuardedBy("mQuotaLock")
186 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap();
187 /** Set of UIDs blacklisted on metered networks. */
188 @GuardedBy("mRulesLock")
189 private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray();
190 /** Set of UIDs whitelisted on metered networks. */
191 @GuardedBy("mRulesLock")
192 private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray();
193 /** Set of UIDs with cleartext penalties. */
194 @GuardedBy("mQuotaLock")
195 private SparseIntArray mUidCleartextPolicy = new SparseIntArray();
196 /** Set of UIDs that are to be blocked/allowed by firewall controller. */
197 @GuardedBy("mRulesLock")
198 private SparseIntArray mUidFirewallRules = new SparseIntArray();
200 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
201 * to application idles.
203 @GuardedBy("mRulesLock")
204 private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
206 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
209 @GuardedBy("mRulesLock")
210 private SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
212 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches
213 * to device on power-save mode.
215 @GuardedBy("mRulesLock")
216 private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
217 /** Set of states for the child firewall chains. True if the chain is active. */
218 @GuardedBy("mRulesLock")
219 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
221 @GuardedBy("mQuotaLock")
222 private volatile boolean mDataSaverMode;
224 private final Object mIdleTimerLock = new Object();
225 /** Set of interfaces with active idle timers. */
226 private static class IdleTimerParams {
227 public final int timeout;
228 public final int type;
229 public int networkCount;
231 IdleTimerParams(int timeout, int type) {
232 this.timeout = timeout;
234 this.networkCount = 1;
237 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
239 private volatile boolean mFirewallEnabled;
240 private volatile boolean mStrictEnabled;
242 private boolean mMobileActivityFromRadio = false;
243 private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
244 private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
246 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
247 new RemoteCallbackList<>();
248 private boolean mNetworkActive;
251 * Constructs a new NetworkManagementService instance
253 * @param context Binder context for this service
255 private NetworkManagementService(
256 Context context, SystemServices services) {
258 mServices = services;
260 mDaemonHandler = new Handler(FgThread.get().getLooper());
262 mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener();
264 mServices.registerLocalService(new LocalService());
266 synchronized (mTetheringStatsProviders) {
267 mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd");
272 NetworkManagementService() {
274 mDaemonHandler = null;
276 mNetdUnsolicitedEventListener = null;
279 static NetworkManagementService create(Context context, SystemServices services)
280 throws InterruptedException {
281 final NetworkManagementService service =
282 new NetworkManagementService(context, services);
283 if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
284 if (DBG) Slog.d(TAG, "Connecting native netd service");
285 service.connectNativeNetdService();
286 if (DBG) Slog.d(TAG, "Connected");
290 public static NetworkManagementService create(Context context) throws InterruptedException {
291 return create(context, new SystemServices());
294 public void systemReady() {
296 final long start = System.currentTimeMillis();
297 prepareNativeDaemon();
298 final long delta = System.currentTimeMillis() - start;
299 Slog.d(TAG, "Prepared in " + delta + "ms");
302 prepareNativeDaemon();
306 private IBatteryStats getBatteryStats() {
307 synchronized (this) {
308 if (mBatteryStats != null) {
309 return mBatteryStats;
312 IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME));
313 return mBatteryStats;
318 public void registerObserver(INetworkManagementEventObserver observer) {
319 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
320 mObservers.register(observer);
324 public void unregisterObserver(INetworkManagementEventObserver observer) {
325 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
326 mObservers.unregister(observer);
330 private interface NetworkManagementEventCallback {
331 public void sendCallback(INetworkManagementEventObserver o) throws RemoteException;
334 private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) {
335 final int length = mObservers.beginBroadcast();
337 for (int i = 0; i < length; i++) {
339 eventCallback.sendCallback(mObservers.getBroadcastItem(i));
340 } catch (RemoteException | RuntimeException e) {
344 mObservers.finishBroadcast();
349 * Notify our observers of an interface status change
351 private void notifyInterfaceStatusChanged(String iface, boolean up) {
352 invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up));
356 * Notify our observers of an interface link state change
357 * (typically, an Ethernet cable has been plugged-in or unplugged).
359 private void notifyInterfaceLinkStateChanged(String iface, boolean up) {
360 invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up));
364 * Notify our observers of an interface addition.
366 private void notifyInterfaceAdded(String iface) {
367 invokeForAllObservers(o -> o.interfaceAdded(iface));
371 * Notify our observers of an interface removal.
373 private void notifyInterfaceRemoved(String iface) {
374 // netd already clears out quota and alerts for removed ifaces; update
375 // our sanity-checking state.
376 mActiveAlerts.remove(iface);
377 mActiveQuotas.remove(iface);
378 invokeForAllObservers(o -> o.interfaceRemoved(iface));
382 * Notify our observers of a limit reached.
384 private void notifyLimitReached(String limitName, String iface) {
385 invokeForAllObservers(o -> o.limitReached(limitName, iface));
389 * Notify our observers of a change in the data activity state of the interface
391 private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
392 int uid, boolean fromRadio) {
393 final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
394 int powerState = isActive
395 ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
396 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
399 if (mMobileActivityFromRadio) {
400 // If this call is not coming from a report from the radio itself, but we
401 // have previously received reports from the radio, then we will take the
402 // power state to just be whatever the radio last reported.
403 powerState = mLastPowerStateFromRadio;
406 mMobileActivityFromRadio = true;
408 if (mLastPowerStateFromRadio != powerState) {
409 mLastPowerStateFromRadio = powerState;
411 getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
412 } catch (RemoteException e) {
414 StatsLog.write_non_chained(StatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null,
419 if (ConnectivityManager.isNetworkTypeWifi(type)) {
420 if (mLastPowerStateFromWifi != powerState) {
421 mLastPowerStateFromWifi = powerState;
423 getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
424 } catch (RemoteException e) {
426 StatsLog.write_non_chained(StatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null,
431 if (!isMobile || fromRadio || !mMobileActivityFromRadio) {
432 // Report the change in data activity. We don't do this if this is a change
433 // on the mobile network, that is not coming from the radio itself, and we
434 // have previously seen change reports from the radio. In that case only
435 // the radio is the authority for the current state.
436 final boolean active = isActive;
437 invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
438 Integer.toString(type), active, tsNanos));
441 boolean report = false;
442 synchronized (mIdleTimerLock) {
443 if (mActiveIdleTimers.isEmpty()) {
444 // If there are no idle timers, we are not monitoring activity, so we
445 // are always considered active.
448 if (mNetworkActive != isActive) {
449 mNetworkActive = isActive;
454 reportNetworkActive();
459 public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) {
460 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
461 Preconditions.checkNotNull(provider);
462 synchronized(mTetheringStatsProviders) {
463 mTetheringStatsProviders.put(provider, name);
468 public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) {
469 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
470 synchronized(mTetheringStatsProviders) {
471 mTetheringStatsProviders.remove(provider);
476 public void tetherLimitReached(ITetheringStatsProvider provider) {
477 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
478 synchronized(mTetheringStatsProviders) {
479 if (!mTetheringStatsProviders.containsKey(provider)) {
482 // No current code examines the interface parameter in a global alert. Just pass null.
483 mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null));
487 // Sync the state of the given chain with the native daemon.
488 private void syncFirewallChainLocked(int chain, String name) {
489 SparseIntArray rules;
490 synchronized (mRulesLock) {
491 final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
492 // Make a copy of the current rules, and then clear them. This is because
493 // setFirewallUidRuleInternal only pushes down rules to the native daemon if they
494 // are different from the current rules stored in the mUidFirewall*Rules array for
495 // the specified chain. If we don't clear the rules, setFirewallUidRuleInternal
497 rules = uidFirewallRules.clone();
498 uidFirewallRules.clear();
500 if (rules.size() > 0) {
501 // Now push the rules. setFirewallUidRuleInternal will push each of these down to the
502 // native daemon, and also add them to the mUidFirewall*Rules array for the specified
504 if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall "
505 + name + "UID rules");
506 for (int i = 0; i < rules.size(); i++) {
507 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i));
512 private void connectNativeNetdService() {
513 mNetdService = mServices.getNetd();
515 mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener);
516 if (DBG) Slog.d(TAG, "Register unsolicited event listener");
517 } catch (RemoteException | ServiceSpecificException e) {
518 Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e);
523 * Prepare native daemon once connected, enabling modules and pushing any
524 * existing in-memory rules.
526 private void prepareNativeDaemon() {
528 // push any existing quota or UID rules
529 synchronized (mQuotaLock) {
531 // Netd unconditionally enable bandwidth control
532 SystemProperties.set(PROP_QTAGUID_ENABLED, "1");
534 mStrictEnabled = true;
536 setDataSaverModeEnabled(mDataSaverMode);
538 int size = mActiveQuotas.size();
540 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules");
541 final HashMap<String, Long> activeQuotas = mActiveQuotas;
542 mActiveQuotas = Maps.newHashMap();
543 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) {
544 setInterfaceQuota(entry.getKey(), entry.getValue());
548 size = mActiveAlerts.size();
550 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules");
551 final HashMap<String, Long> activeAlerts = mActiveAlerts;
552 mActiveAlerts = Maps.newHashMap();
553 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) {
554 setInterfaceAlert(entry.getKey(), entry.getValue());
558 SparseBooleanArray uidRejectOnQuota = null;
559 SparseBooleanArray uidAcceptOnQuota = null;
560 synchronized (mRulesLock) {
561 size = mUidRejectOnMetered.size();
563 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules");
564 uidRejectOnQuota = mUidRejectOnMetered;
565 mUidRejectOnMetered = new SparseBooleanArray();
568 size = mUidAllowOnMetered.size();
570 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules");
571 uidAcceptOnQuota = mUidAllowOnMetered;
572 mUidAllowOnMetered = new SparseBooleanArray();
575 if (uidRejectOnQuota != null) {
576 for (int i = 0; i < uidRejectOnQuota.size(); i++) {
577 setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i),
578 uidRejectOnQuota.valueAt(i));
581 if (uidAcceptOnQuota != null) {
582 for (int i = 0; i < uidAcceptOnQuota.size(); i++) {
583 setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i),
584 uidAcceptOnQuota.valueAt(i));
588 size = mUidCleartextPolicy.size();
590 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies");
591 final SparseIntArray local = mUidCleartextPolicy;
592 mUidCleartextPolicy = new SparseIntArray();
593 for (int i = 0; i < local.size(); i++) {
594 setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i));
598 setFirewallEnabled(mFirewallEnabled);
600 syncFirewallChainLocked(FIREWALL_CHAIN_NONE, "");
601 syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby ");
602 syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable ");
603 syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
606 {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE};
607 for (int chain : chains) {
608 if (getFirewallChainState(chain)) {
609 setFirewallChainEnabled(chain, true);
616 getBatteryStats().noteNetworkStatsEnabled();
617 } catch (RemoteException e) {
623 * Notify our observers of a new or updated interface address.
625 private void notifyAddressUpdated(String iface, LinkAddress address) {
626 invokeForAllObservers(o -> o.addressUpdated(iface, address));
630 * Notify our observers of a deleted interface address.
632 private void notifyAddressRemoved(String iface, LinkAddress address) {
633 invokeForAllObservers(o -> o.addressRemoved(iface, address));
637 * Notify our observers of DNS server information received.
639 private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
640 invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses));
644 * Notify our observers of a route change.
646 private void notifyRouteChange(boolean updated, RouteInfo route) {
648 invokeForAllObservers(o -> o.routeUpdated(route));
650 invokeForAllObservers(o -> o.routeRemoved(route));
654 private class NetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub {
656 public void onInterfaceClassActivityChanged(boolean isActive,
657 int label, long timestamp, int uid) throws RemoteException {
658 final long timestampNanos;
659 if (timestamp <= 0) {
660 timestampNanos = SystemClock.elapsedRealtimeNanos();
662 timestampNanos = timestamp;
664 mDaemonHandler.post(() ->
665 notifyInterfaceClassActivity(label, isActive, timestampNanos, uid, false));
669 public void onQuotaLimitReached(String alertName, String ifName)
670 throws RemoteException {
671 mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName));
675 public void onInterfaceDnsServerInfo(String ifName,
676 long lifetime, String[] servers) throws RemoteException {
677 mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers));
681 public void onInterfaceAddressUpdated(String addr,
682 String ifName, int flags, int scope) throws RemoteException {
683 final LinkAddress address = new LinkAddress(addr, flags, scope);
684 mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address));
688 public void onInterfaceAddressRemoved(String addr,
689 String ifName, int flags, int scope) throws RemoteException {
690 final LinkAddress address = new LinkAddress(addr, flags, scope);
691 mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address));
695 public void onInterfaceAdded(String ifName) throws RemoteException {
696 mDaemonHandler.post(() -> notifyInterfaceAdded(ifName));
700 public void onInterfaceRemoved(String ifName) throws RemoteException {
701 mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName));
705 public void onInterfaceChanged(String ifName, boolean up)
706 throws RemoteException {
707 mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up));
711 public void onInterfaceLinkStateChanged(String ifName, boolean up)
712 throws RemoteException {
713 mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up));
717 public void onRouteChanged(boolean updated,
718 String route, String gateway, String ifName) throws RemoteException {
719 final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
720 ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
722 mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute));
726 public void onStrictCleartextDetected(int uid, String hex) throws RemoteException {
727 // Don't need to post to mDaemonHandler because the only thing
728 // that notifyCleartextNetwork does is post to a handler
729 ActivityManager.getService().notifyCleartextNetwork(uid,
730 HexDump.hexStringToByteArray(hex));
734 public int getInterfaceVersion() {
735 return INetdUnsolicitedEventListener.VERSION;
740 // INetworkManagementService members
743 public String[] listInterfaces() {
744 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
746 return mNetdService.interfaceGetList();
747 } catch (RemoteException | ServiceSpecificException e) {
748 throw new IllegalStateException(e);
753 * Convert InterfaceConfiguration to InterfaceConfigurationParcel with given ifname.
755 private static InterfaceConfigurationParcel toStableParcel(InterfaceConfiguration cfg,
757 InterfaceConfigurationParcel cfgParcel = new InterfaceConfigurationParcel();
758 cfgParcel.ifName = iface;
759 String hwAddr = cfg.getHardwareAddress();
760 if (!TextUtils.isEmpty(hwAddr)) {
761 cfgParcel.hwAddr = hwAddr;
763 cfgParcel.hwAddr = "";
765 cfgParcel.ipv4Addr = cfg.getLinkAddress().getAddress().getHostAddress();
766 cfgParcel.prefixLength = cfg.getLinkAddress().getPrefixLength();
767 ArrayList<String> flags = new ArrayList<>();
768 for (String flag : cfg.getFlags()) {
771 cfgParcel.flags = flags.toArray(new String[0]);
777 * Construct InterfaceConfiguration from InterfaceConfigurationParcel.
779 public static InterfaceConfiguration fromStableParcel(InterfaceConfigurationParcel p) {
780 InterfaceConfiguration cfg = new InterfaceConfiguration();
781 cfg.setHardwareAddress(p.hwAddr);
783 final InetAddress addr = NetworkUtils.numericToInetAddress(p.ipv4Addr);
784 cfg.setLinkAddress(new LinkAddress(addr, p.prefixLength));
785 for (String flag : p.flags) {
793 public InterfaceConfiguration getInterfaceConfig(String iface) {
794 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
795 final InterfaceConfigurationParcel result;
797 result = mNetdService.interfaceGetCfg(iface);
798 } catch (RemoteException | ServiceSpecificException e) {
799 throw new IllegalStateException(e);
803 final InterfaceConfiguration cfg = fromStableParcel(result);
805 } catch (IllegalArgumentException iae) {
806 throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae);
811 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
812 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
813 LinkAddress linkAddr = cfg.getLinkAddress();
814 if (linkAddr == null || linkAddr.getAddress() == null) {
815 throw new IllegalStateException("Null LinkAddress given");
818 final InterfaceConfigurationParcel cfgParcel = toStableParcel(cfg, iface);
821 mNetdService.interfaceSetCfg(cfgParcel);
822 } catch (RemoteException | ServiceSpecificException e) {
823 throw new IllegalStateException(e);
828 public void setInterfaceDown(String iface) {
829 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
830 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
831 ifcg.setInterfaceDown();
832 setInterfaceConfig(iface, ifcg);
836 public void setInterfaceUp(String iface) {
837 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
838 final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
839 ifcg.setInterfaceUp();
840 setInterfaceConfig(iface, ifcg);
844 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
845 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
847 mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable);
848 } catch (RemoteException | ServiceSpecificException e) {
849 throw new IllegalStateException(e);
853 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
854 IPv6 addresses on interface down, but we need to do full clean up here */
856 public void clearInterfaceAddresses(String iface) {
857 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
859 mNetdService.interfaceClearAddrs(iface);
860 } catch (RemoteException | ServiceSpecificException e) {
861 throw new IllegalStateException(e);
866 public void enableIpv6(String iface) {
867 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
869 mNetdService.interfaceSetEnableIPv6(iface, true);
870 } catch (RemoteException | ServiceSpecificException e) {
871 throw new IllegalStateException(e);
876 public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
878 mNetdService.setIPv6AddrGenMode(iface, mode);
879 } catch (RemoteException e) {
880 throw e.rethrowAsRuntimeException();
885 public void disableIpv6(String iface) {
886 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
888 mNetdService.interfaceSetEnableIPv6(iface, false);
889 } catch (RemoteException | ServiceSpecificException e) {
890 throw new IllegalStateException(e);
895 public void addRoute(int netId, RouteInfo route) {
896 modifyRoute(MODIFY_OPERATION_ADD, netId, route);
900 public void removeRoute(int netId, RouteInfo route) {
901 modifyRoute(MODIFY_OPERATION_REMOVE, netId, route);
904 private void modifyRoute(boolean add, int netId, RouteInfo route) {
905 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
907 final String ifName = route.getInterface();
908 final String dst = route.getDestination().toString();
909 final String nextHop;
911 switch (route.getType()) {
912 case RouteInfo.RTN_UNICAST:
913 if (route.hasGateway()) {
914 nextHop = route.getGateway().getHostAddress();
916 nextHop = INetd.NEXTHOP_NONE;
919 case RouteInfo.RTN_UNREACHABLE:
920 nextHop = INetd.NEXTHOP_UNREACHABLE;
922 case RouteInfo.RTN_THROW:
923 nextHop = INetd.NEXTHOP_THROW;
926 nextHop = INetd.NEXTHOP_NONE;
931 mNetdService.networkAddRoute(netId, ifName, dst, nextHop);
933 mNetdService.networkRemoveRoute(netId, ifName, dst, nextHop);
935 } catch (RemoteException | ServiceSpecificException e) {
936 throw new IllegalStateException(e);
940 private ArrayList<String> readRouteList(String filename) {
941 FileInputStream fstream = null;
942 ArrayList<String> list = new ArrayList<>();
945 fstream = new FileInputStream(filename);
946 DataInputStream in = new DataInputStream(fstream);
947 BufferedReader br = new BufferedReader(new InputStreamReader(in));
950 // throw away the title line
952 while (((s = br.readLine()) != null) && (s.length() != 0)) {
955 } catch (IOException ex) {
956 // return current list, possibly empty
958 if (fstream != null) {
961 } catch (IOException ex) {}
969 public void setMtu(String iface, int mtu) {
970 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
973 mNetdService.interfaceSetMtu(iface, mtu);
974 } catch (RemoteException | ServiceSpecificException e) {
975 throw new IllegalStateException(e);
980 public void shutdown() {
981 // TODO: remove from aidl if nobody calls externally
982 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
984 Slog.i(TAG, "Shutting down");
988 public boolean getIpForwardingEnabled() throws IllegalStateException{
989 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
992 final boolean isEnabled = mNetdService.ipfwdEnabled();
994 } catch (RemoteException | ServiceSpecificException e) {
995 throw new IllegalStateException(e);
1000 public void setIpForwardingEnabled(boolean enable) {
1001 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1004 mNetdService.ipfwdEnableForwarding("tethering");
1006 mNetdService.ipfwdDisableForwarding("tethering");
1008 } catch (RemoteException | ServiceSpecificException e) {
1009 throw new IllegalStateException(e);
1014 public void startTethering(String[] dhcpRange) {
1015 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1016 // an odd number of addrs will fail
1019 mNetdService.tetherStart(dhcpRange);
1020 } catch (RemoteException | ServiceSpecificException e) {
1021 throw new IllegalStateException(e);
1026 public void stopTethering() {
1027 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1029 mNetdService.tetherStop();
1030 } catch (RemoteException | ServiceSpecificException e) {
1031 throw new IllegalStateException(e);
1036 public boolean isTetheringStarted() {
1037 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1040 final boolean isEnabled = mNetdService.tetherIsEnabled();
1042 } catch (RemoteException | ServiceSpecificException e) {
1043 throw new IllegalStateException(e);
1048 public void tetherInterface(String iface) {
1049 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1051 mNetdService.tetherInterfaceAdd(iface);
1052 } catch (RemoteException | ServiceSpecificException e) {
1053 throw new IllegalStateException(e);
1055 List<RouteInfo> routes = new ArrayList<>();
1056 // The RouteInfo constructor truncates the LinkAddress to a network prefix, thus making it
1057 // suitable to use as a route destination.
1058 routes.add(new RouteInfo(getInterfaceConfig(iface).getLinkAddress(), null, iface));
1059 addInterfaceToLocalNetwork(iface, routes);
1063 public void untetherInterface(String iface) {
1064 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1066 mNetdService.tetherInterfaceRemove(iface);
1067 } catch (RemoteException | ServiceSpecificException e) {
1068 throw new IllegalStateException(e);
1070 removeInterfaceFromLocalNetwork(iface);
1075 public String[] listTetheredInterfaces() {
1076 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1078 return mNetdService.tetherInterfaceList();
1079 } catch (RemoteException | ServiceSpecificException e) {
1080 throw new IllegalStateException(e);
1085 public void setDnsForwarders(Network network, String[] dns) {
1086 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1088 int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
1091 mNetdService.tetherDnsSet(netId, dns);
1092 } catch (RemoteException | ServiceSpecificException e) {
1093 throw new IllegalStateException(e);
1098 public String[] getDnsForwarders() {
1099 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1101 return mNetdService.tetherDnsList();
1102 } catch (RemoteException | ServiceSpecificException e) {
1103 throw new IllegalStateException(e);
1107 private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) {
1108 ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size());
1109 for (InterfaceAddress ia : addresses) {
1110 if (!ia.getAddress().isLinkLocalAddress())
1116 private void modifyInterfaceForward(boolean add, String fromIface, String toIface) {
1119 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface);
1121 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface);
1123 } catch (RemoteException | ServiceSpecificException e) {
1124 throw new IllegalStateException(e);
1129 public void startInterfaceForwarding(String fromIface, String toIface) {
1130 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1131 modifyInterfaceForward(true, fromIface, toIface);
1135 public void stopInterfaceForwarding(String fromIface, String toIface) {
1136 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1137 modifyInterfaceForward(false, fromIface, toIface);
1141 public void enableNat(String internalInterface, String externalInterface) {
1142 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1144 mNetdService.tetherAddForward(internalInterface, externalInterface);
1145 } catch (RemoteException | ServiceSpecificException e) {
1146 throw new IllegalStateException(e);
1151 public void disableNat(String internalInterface, String externalInterface) {
1152 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1154 mNetdService.tetherRemoveForward(internalInterface, externalInterface);
1155 } catch (RemoteException | ServiceSpecificException e) {
1156 throw new IllegalStateException(e);
1161 public void addIdleTimer(String iface, int timeout, final int type) {
1162 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1164 if (DBG) Slog.d(TAG, "Adding idletimer");
1166 synchronized (mIdleTimerLock) {
1167 IdleTimerParams params = mActiveIdleTimers.get(iface);
1168 if (params != null) {
1169 // the interface already has idletimer, update network count
1170 params.networkCount++;
1175 mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
1176 } catch (RemoteException | ServiceSpecificException e) {
1177 throw new IllegalStateException(e);
1179 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
1181 // Networks start up.
1182 if (ConnectivityManager.isNetworkTypeMobile(type)) {
1183 mNetworkActive = false;
1185 mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
1186 SystemClock.elapsedRealtimeNanos(), -1, false));
1191 public void removeIdleTimer(String iface) {
1192 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1194 if (DBG) Slog.d(TAG, "Removing idletimer");
1196 synchronized (mIdleTimerLock) {
1197 final IdleTimerParams params = mActiveIdleTimers.get(iface);
1198 if (params == null || --(params.networkCount) > 0) {
1203 mNetdService.idletimerRemoveInterface(iface,
1204 params.timeout, Integer.toString(params.type));
1205 } catch (RemoteException | ServiceSpecificException e) {
1206 throw new IllegalStateException(e);
1208 mActiveIdleTimers.remove(iface);
1209 mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
1210 SystemClock.elapsedRealtimeNanos(), -1, false));
1215 public NetworkStats getNetworkStatsSummaryDev() {
1216 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1218 return mStatsFactory.readNetworkStatsSummaryDev();
1219 } catch (IOException e) {
1220 throw new IllegalStateException(e);
1225 public NetworkStats getNetworkStatsSummaryXt() {
1226 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1228 return mStatsFactory.readNetworkStatsSummaryXt();
1229 } catch (IOException e) {
1230 throw new IllegalStateException(e);
1235 public NetworkStats getNetworkStatsDetail() {
1236 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1238 return mStatsFactory.readNetworkStatsDetail();
1239 } catch (IOException e) {
1240 throw new IllegalStateException(e);
1245 public void setInterfaceQuota(String iface, long quotaBytes) {
1246 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1248 synchronized (mQuotaLock) {
1249 if (mActiveQuotas.containsKey(iface)) {
1250 throw new IllegalStateException("iface " + iface + " already has quota");
1254 // TODO: support quota shared across interfaces
1255 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes);
1257 mActiveQuotas.put(iface, quotaBytes);
1258 } catch (RemoteException | ServiceSpecificException e) {
1259 throw new IllegalStateException(e);
1262 synchronized (mTetheringStatsProviders) {
1263 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1265 provider.setInterfaceQuota(iface, quotaBytes);
1266 } catch (RemoteException e) {
1267 Log.e(TAG, "Problem setting tethering data limit on provider " +
1268 mTetheringStatsProviders.get(provider) + ": " + e);
1276 public void removeInterfaceQuota(String iface) {
1277 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1279 synchronized (mQuotaLock) {
1280 if (!mActiveQuotas.containsKey(iface)) {
1281 // TODO: eventually consider throwing
1285 mActiveQuotas.remove(iface);
1286 mActiveAlerts.remove(iface);
1289 // TODO: support quota shared across interfaces
1290 mNetdService.bandwidthRemoveInterfaceQuota(iface);
1291 } catch (RemoteException | ServiceSpecificException e) {
1292 throw new IllegalStateException(e);
1295 synchronized (mTetheringStatsProviders) {
1296 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {
1298 provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED);
1299 } catch (RemoteException e) {
1300 Log.e(TAG, "Problem removing tethering data limit on provider " +
1301 mTetheringStatsProviders.get(provider) + ": " + e);
1309 public void setInterfaceAlert(String iface, long alertBytes) {
1310 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1312 // quick sanity check
1313 if (!mActiveQuotas.containsKey(iface)) {
1314 throw new IllegalStateException("setting alert requires existing quota on iface");
1317 synchronized (mQuotaLock) {
1318 if (mActiveAlerts.containsKey(iface)) {
1319 throw new IllegalStateException("iface " + iface + " already has alert");
1323 // TODO: support alert shared across interfaces
1324 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes);
1325 mActiveAlerts.put(iface, alertBytes);
1326 } catch (RemoteException | ServiceSpecificException e) {
1327 throw new IllegalStateException(e);
1333 public void removeInterfaceAlert(String iface) {
1334 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1336 synchronized (mQuotaLock) {
1337 if (!mActiveAlerts.containsKey(iface)) {
1338 // TODO: eventually consider throwing
1343 // TODO: support alert shared across interfaces
1344 mNetdService.bandwidthRemoveInterfaceAlert(iface);
1345 mActiveAlerts.remove(iface);
1346 } catch (RemoteException | ServiceSpecificException e) {
1347 throw new IllegalStateException(e);
1353 public void setGlobalAlert(long alertBytes) {
1354 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1357 mNetdService.bandwidthSetGlobalAlert(alertBytes);
1358 } catch (RemoteException | ServiceSpecificException e) {
1359 throw new IllegalStateException(e);
1363 private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) {
1364 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1366 synchronized (mQuotaLock) {
1368 SparseBooleanArray quotaList;
1369 synchronized (mRulesLock) {
1370 quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered;
1371 oldEnable = quotaList.get(uid, false);
1373 if (oldEnable == enable) {
1374 // TODO: eventually consider throwing
1378 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth");
1382 mNetdService.bandwidthAddNaughtyApp(uid);
1384 mNetdService.bandwidthRemoveNaughtyApp(uid);
1388 mNetdService.bandwidthAddNiceApp(uid);
1390 mNetdService.bandwidthRemoveNiceApp(uid);
1393 synchronized (mRulesLock) {
1395 quotaList.put(uid, true);
1397 quotaList.delete(uid);
1400 } catch (RemoteException | ServiceSpecificException e) {
1401 throw new IllegalStateException(e);
1403 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
1409 public void setUidMeteredNetworkBlacklist(int uid, boolean enable) {
1410 setUidOnMeteredNetworkList(uid, true, enable);
1414 public void setUidMeteredNetworkWhitelist(int uid, boolean enable) {
1415 setUidOnMeteredNetworkList(uid, false, enable);
1419 public boolean setDataSaverModeEnabled(boolean enable) {
1420 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG);
1422 if (DBG) Log.d(TAG, "setDataSaverMode: " + enable);
1423 synchronized (mQuotaLock) {
1424 if (mDataSaverMode == enable) {
1425 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode);
1428 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver");
1430 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable);
1432 mDataSaverMode = enable;
1434 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed");
1437 } catch (RemoteException e) {
1438 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e);
1441 Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
1446 private static UidRangeParcel makeUidRangeParcel(int start, int stop) {
1447 UidRangeParcel range = new UidRangeParcel();
1448 range.start = start;
1453 private static UidRangeParcel[] toStableParcels(UidRange[] ranges) {
1454 UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length];
1455 for (int i = 0; i < ranges.length; i++) {
1456 stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop);
1458 return stableRanges;
1462 public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)
1463 throws ServiceSpecificException {
1464 mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG);
1466 mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges));
1467 } catch (ServiceSpecificException e) {
1468 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1469 + ": netd command failed", e);
1471 } catch (RemoteException e) {
1472 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")"
1473 + ": netd command failed", e);
1474 throw e.rethrowAsRuntimeException();
1478 private void applyUidCleartextNetworkPolicy(int uid, int policy) {
1479 final int policyValue;
1481 case StrictMode.NETWORK_POLICY_ACCEPT:
1482 policyValue = INetd.PENALTY_POLICY_ACCEPT;
1484 case StrictMode.NETWORK_POLICY_LOG:
1485 policyValue = INetd.PENALTY_POLICY_LOG;
1487 case StrictMode.NETWORK_POLICY_REJECT:
1488 policyValue = INetd.PENALTY_POLICY_REJECT;
1491 throw new IllegalArgumentException("Unknown policy " + policy);
1495 mNetdService.strictUidCleartextPenalty(uid, policyValue);
1496 mUidCleartextPolicy.put(uid, policy);
1497 } catch (RemoteException | ServiceSpecificException e) {
1498 throw new IllegalStateException(e);
1503 public void setUidCleartextNetworkPolicy(int uid, int policy) {
1504 if (Binder.getCallingUid() != uid) {
1505 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1508 synchronized (mQuotaLock) {
1509 final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT);
1510 if (oldPolicy == policy) {
1511 // This also ensures we won't needlessly apply an ACCEPT policy if we've just
1512 // enabled strict and the underlying iptables rules are empty.
1516 // TODO: remove this code after removing prepareNativeDaemon()
1517 if (!mStrictEnabled) {
1518 // Module isn't enabled yet; stash the requested policy away to
1519 // apply later once the daemon is connected.
1520 mUidCleartextPolicy.put(uid, policy);
1524 // netd does not keep state on strict mode policies, and cannot replace a non-accept
1525 // policy without deleting it first. Rather than add state to netd, just always send
1526 // it an accept policy when switching between two non-accept policies.
1527 // TODO: consider keeping state in netd so we can simplify this code.
1528 if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT &&
1529 policy != StrictMode.NETWORK_POLICY_ACCEPT) {
1530 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT);
1533 applyUidCleartextNetworkPolicy(uid, policy);
1538 public boolean isBandwidthControlEnabled() {
1539 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1544 public NetworkStats getNetworkStatsUidDetail(int uid, String[] ifaces) {
1545 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1547 return mStatsFactory.readNetworkStatsDetail(uid, ifaces, TAG_ALL);
1548 } catch (IOException e) {
1549 throw new IllegalStateException(e);
1553 private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
1555 public NetworkStats getTetherStats(int how) {
1556 // We only need to return per-UID stats. Per-device stats are already counted by
1557 // interface counters.
1558 if (how != STATS_PER_UID) {
1559 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
1562 final TetherStatsParcel[] tetherStatsVec;
1564 tetherStatsVec = mNetdService.tetherGetStats();
1565 } catch (RemoteException | ServiceSpecificException e) {
1566 throw new IllegalStateException("problem parsing tethering stats: ", e);
1569 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
1570 tetherStatsVec.length);
1571 final NetworkStats.Entry entry = new NetworkStats.Entry();
1573 for (TetherStatsParcel tetherStats : tetherStatsVec) {
1575 entry.iface = tetherStats.iface;
1576 entry.uid = UID_TETHERING;
1577 entry.set = SET_DEFAULT;
1578 entry.tag = TAG_NONE;
1579 entry.rxBytes = tetherStats.rxBytes;
1580 entry.rxPackets = tetherStats.rxPackets;
1581 entry.txBytes = tetherStats.txBytes;
1582 entry.txPackets = tetherStats.txPackets;
1583 stats.combineValues(entry);
1584 } catch (ArrayIndexOutOfBoundsException e) {
1585 throw new IllegalStateException("invalid tethering stats " + e);
1593 public void setInterfaceQuota(String iface, long quotaBytes) {
1594 // Do nothing. netd is already informed of quota changes in setInterfaceQuota.
1599 public NetworkStats getNetworkStatsTethering(int how) {
1600 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1602 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
1603 synchronized (mTetheringStatsProviders) {
1604 for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) {
1606 stats.combineAllValues(provider.getTetherStats(how));
1607 } catch (RemoteException e) {
1608 Log.e(TAG, "Problem reading tethering stats from " +
1609 mTetheringStatsProviders.get(provider) + ": " + e);
1617 public void addVpnUidRanges(int netId, UidRange[] ranges) {
1618 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1621 mNetdService.networkAddUidRanges(netId, toStableParcels(ranges));
1622 } catch (RemoteException | ServiceSpecificException e) {
1623 throw new IllegalStateException(e);
1628 public void removeVpnUidRanges(int netId, UidRange[] ranges) {
1629 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1631 mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges));
1632 } catch (RemoteException | ServiceSpecificException e) {
1633 throw new IllegalStateException(e);
1638 public void setFirewallEnabled(boolean enabled) {
1641 mNetdService.firewallSetFirewallType(
1642 enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST);
1643 mFirewallEnabled = enabled;
1644 } catch (RemoteException | ServiceSpecificException e) {
1645 throw new IllegalStateException(e);
1650 public boolean isFirewallEnabled() {
1652 return mFirewallEnabled;
1656 public void setFirewallInterfaceRule(String iface, boolean allow) {
1658 Preconditions.checkState(mFirewallEnabled);
1660 mNetdService.firewallSetInterfaceRule(iface,
1661 allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY);
1662 } catch (RemoteException | ServiceSpecificException e) {
1663 throw new IllegalStateException(e);
1667 private void closeSocketsForFirewallChainLocked(int chain, String chainName) {
1668 // UID ranges to close sockets on.
1669 UidRangeParcel[] ranges;
1670 // UID ranges whose sockets we won't touch.
1674 if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
1675 if (getFirewallType(chain) == FIREWALL_WHITELIST) {
1676 // Close all sockets on all non-system UIDs...
1677 ranges = new UidRangeParcel[] {
1678 // TODO: is there a better way of finding all existing users? If so, we could
1679 // specify their ranges here.
1680 makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE),
1682 // ... except for the UIDs that have allow rules.
1683 synchronized (mRulesLock) {
1684 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1685 exemptUids = new int[rules.size()];
1686 for (int i = 0; i < exemptUids.length; i++) {
1687 if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) {
1688 exemptUids[numUids] = rules.keyAt(i);
1693 // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length.
1694 // But the code does not guarantee this in any way, and at least in one case - if we add
1695 // a UID rule to the firewall, and then disable the firewall - the chains can contain
1696 // the wrong type of rule. In this case, don't close connections that we shouldn't.
1698 // TODO: tighten up this code by ensuring we never set the wrong type of rule, and
1699 // fix setFirewallEnabled to grab mQuotaLock and clear rules.
1700 if (numUids != exemptUids.length) {
1701 exemptUids = Arrays.copyOf(exemptUids, numUids);
1704 // Close sockets for every UID that has a deny rule...
1705 synchronized (mRulesLock) {
1706 final SparseIntArray rules = getUidFirewallRulesLR(chain);
1707 ranges = new UidRangeParcel[rules.size()];
1708 for (int i = 0; i < ranges.length; i++) {
1709 if (rules.valueAt(i) == FIREWALL_RULE_DENY) {
1710 int uid = rules.keyAt(i);
1711 ranges[numUids] = makeUidRangeParcel(uid, uid);
1716 // As above; usually numUids == ranges.length, but not always.
1717 if (numUids != ranges.length) {
1718 ranges = Arrays.copyOf(ranges, numUids);
1720 // ... with no exceptions.
1721 exemptUids = new int[0];
1725 mNetdService.socketDestroy(ranges, exemptUids);
1726 } catch(RemoteException | ServiceSpecificException e) {
1727 Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e);
1732 public void setFirewallChainEnabled(int chain, boolean enable) {
1734 synchronized (mQuotaLock) {
1735 synchronized (mRulesLock) {
1736 if (getFirewallChainState(chain) == enable) {
1737 // All is the same, nothing to do. This relies on the fact that netd has child
1738 // chains default detached.
1741 setFirewallChainState(chain, enable);
1744 final String chainName = getFirewallChainName(chain);
1745 if (chain == FIREWALL_CHAIN_NONE) {
1746 throw new IllegalArgumentException("Bad child chain: " + chainName);
1750 mNetdService.firewallEnableChildChain(chain, enable);
1751 } catch (RemoteException | ServiceSpecificException e) {
1752 throw new IllegalStateException(e);
1755 // Close any sockets that were opened by the affected UIDs. This has to be done after
1756 // disabling network connectivity, in case they react to the socket close by reopening
1757 // the connection and race with the iptables commands that enable the firewall. All
1758 // whitelist and blacklist chains allow RSTs through.
1760 closeSocketsForFirewallChainLocked(chain, chainName);
1765 private String getFirewallChainName(int chain) {
1767 case FIREWALL_CHAIN_STANDBY:
1768 return FIREWALL_CHAIN_NAME_STANDBY;
1769 case FIREWALL_CHAIN_DOZABLE:
1770 return FIREWALL_CHAIN_NAME_DOZABLE;
1771 case FIREWALL_CHAIN_POWERSAVE:
1772 return FIREWALL_CHAIN_NAME_POWERSAVE;
1774 throw new IllegalArgumentException("Bad child chain: " + chain);
1778 private int getFirewallType(int chain) {
1780 case FIREWALL_CHAIN_STANDBY:
1781 return FIREWALL_BLACKLIST;
1782 case FIREWALL_CHAIN_DOZABLE:
1783 return FIREWALL_WHITELIST;
1784 case FIREWALL_CHAIN_POWERSAVE:
1785 return FIREWALL_WHITELIST;
1787 return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST;
1792 public void setFirewallUidRules(int chain, int[] uids, int[] rules) {
1794 synchronized (mQuotaLock) {
1795 synchronized (mRulesLock) {
1796 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
1797 SparseIntArray newRules = new SparseIntArray();
1798 // apply new set of rules
1799 for (int index = uids.length - 1; index >= 0; --index) {
1800 int uid = uids[index];
1801 int rule = rules[index];
1802 updateFirewallUidRuleLocked(chain, uid, rule);
1803 newRules.put(uid, rule);
1805 // collect the rules to remove.
1806 SparseIntArray rulesToRemove = new SparseIntArray();
1807 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) {
1808 int uid = uidFirewallRules.keyAt(index);
1809 if (newRules.indexOfKey(uid) < 0) {
1810 rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT);
1813 // remove dead rules
1814 for (int index = rulesToRemove.size() - 1; index >= 0; --index) {
1815 int uid = rulesToRemove.keyAt(index);
1816 updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT);
1821 case FIREWALL_CHAIN_DOZABLE:
1822 mNetdService.firewallReplaceUidChain("fw_dozable", true, uids);
1824 case FIREWALL_CHAIN_STANDBY:
1825 mNetdService.firewallReplaceUidChain("fw_standby", false, uids);
1827 case FIREWALL_CHAIN_POWERSAVE:
1828 mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
1830 case FIREWALL_CHAIN_NONE:
1832 Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
1834 } catch (RemoteException e) {
1835 Slog.w(TAG, "Error flushing firewall chain " + chain, e);
1841 public void setFirewallUidRule(int chain, int uid, int rule) {
1843 synchronized (mQuotaLock) {
1844 setFirewallUidRuleLocked(chain, uid, rule);
1848 private void setFirewallUidRuleLocked(int chain, int uid, int rule) {
1849 if (updateFirewallUidRuleLocked(chain, uid, rule)) {
1850 final int ruleType = getFirewallRuleType(chain, rule);
1852 mNetdService.firewallSetUidRule(chain, uid, ruleType);
1853 } catch (RemoteException | ServiceSpecificException e) {
1854 throw new IllegalStateException(e);
1859 // TODO: now that netd supports batching, NMS should not keep these data structures anymore...
1860 private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) {
1861 synchronized (mRulesLock) {
1862 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain);
1864 final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT);
1866 Slog.d(TAG, "oldRule = " + oldUidFirewallRule
1867 + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain);
1869 if (oldUidFirewallRule == rule) {
1870 if (DBG) Slog.d(TAG, "!!!!! Skipping change");
1871 // TODO: eventually consider throwing
1875 String ruleName = getFirewallRuleName(chain, rule);
1876 String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule);
1878 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
1879 uidFirewallRules.delete(uid);
1881 uidFirewallRules.put(uid, rule);
1883 return !ruleName.equals(oldRuleName);
1887 private @NonNull String getFirewallRuleName(int chain, int rule) {
1889 if (getFirewallType(chain) == FIREWALL_WHITELIST) {
1890 if (rule == FIREWALL_RULE_ALLOW) {
1895 } else { // Blacklist mode
1896 if (rule == FIREWALL_RULE_DENY) {
1905 @GuardedBy("mRulesLock")
1906 private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) {
1908 case FIREWALL_CHAIN_STANDBY:
1909 return mUidFirewallStandbyRules;
1910 case FIREWALL_CHAIN_DOZABLE:
1911 return mUidFirewallDozableRules;
1912 case FIREWALL_CHAIN_POWERSAVE:
1913 return mUidFirewallPowerSaveRules;
1914 case FIREWALL_CHAIN_NONE:
1915 return mUidFirewallRules;
1917 throw new IllegalArgumentException("Unknown chain:" + chain);
1921 private int getFirewallRuleType(int chain, int rule) {
1922 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
1923 return getFirewallType(chain) == FIREWALL_WHITELIST
1924 ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW;
1929 private static void enforceSystemUid() {
1930 final int uid = Binder.getCallingUid();
1931 if (uid != Process.SYSTEM_UID) {
1932 throw new SecurityException("Only available to AID_SYSTEM");
1937 public void registerNetworkActivityListener(INetworkActivityListener listener) {
1938 mNetworkActivityListeners.register(listener);
1942 public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
1943 mNetworkActivityListeners.unregister(listener);
1947 public boolean isNetworkActive() {
1948 synchronized (mNetworkActivityListeners) {
1949 return mNetworkActive || mActiveIdleTimers.isEmpty();
1953 private void reportNetworkActive() {
1954 final int length = mNetworkActivityListeners.beginBroadcast();
1956 for (int i = 0; i < length; i++) {
1958 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
1959 } catch (RemoteException | RuntimeException e) {
1963 mNetworkActivityListeners.finishBroadcast();
1968 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1969 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
1971 pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
1972 pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
1973 pw.print("mNetworkActive="); pw.println(mNetworkActive);
1975 synchronized (mQuotaLock) {
1976 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
1977 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
1978 pw.print("Data saver mode: "); pw.println(mDataSaverMode);
1979 synchronized (mRulesLock) {
1980 dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered);
1981 dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered);
1985 synchronized (mRulesLock) {
1986 dumpUidFirewallRule(pw, "", mUidFirewallRules);
1988 pw.print("UID firewall standby chain enabled: "); pw.println(
1989 getFirewallChainState(FIREWALL_CHAIN_STANDBY));
1990 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
1992 pw.print("UID firewall dozable chain enabled: "); pw.println(
1993 getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
1994 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
1996 pw.println("UID firewall powersave chain enabled: " +
1997 getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
1998 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules);
2001 synchronized (mIdleTimerLock) {
2002 pw.println("Idle timers:");
2003 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
2004 pw.print(" "); pw.print(ent.getKey()); pw.println(":");
2005 IdleTimerParams params = ent.getValue();
2006 pw.print(" timeout="); pw.print(params.timeout);
2007 pw.print(" type="); pw.print(params.type);
2008 pw.print(" networkCount="); pw.println(params.networkCount);
2012 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
2013 pw.print("Netd service status: " );
2014 if (mNetdService == null) {
2015 pw.println("disconnected");
2018 final boolean alive = mNetdService.isAlive();
2019 pw.println(alive ? "alive": "dead");
2020 } catch (RemoteException e) {
2021 pw.println("unreachable");
2026 private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) {
2027 pw.print("UID bandwith control ");
2029 pw.print(" rule: [");
2030 final int size = list.size();
2031 for (int i = 0; i < size; i++) {
2032 pw.print(list.keyAt(i));
2033 if (i < size - 1) pw.print(",");
2038 private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) {
2039 pw.print("UID firewall ");
2041 pw.print(" rule: [");
2042 final int size = rules.size();
2043 for (int i = 0; i < size; i++) {
2044 pw.print(rules.keyAt(i));
2046 pw.print(rules.valueAt(i));
2047 if (i < size - 1) pw.print(",");
2053 public void addInterfaceToNetwork(String iface, int netId) {
2054 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
2058 public void removeInterfaceFromNetwork(String iface, int netId) {
2059 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface);
2062 private void modifyInterfaceInNetwork(boolean add, int netId, String iface) {
2063 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2066 mNetdService.networkAddInterface(netId, iface);
2068 mNetdService.networkRemoveInterface(netId, iface);
2070 } catch (RemoteException | ServiceSpecificException e) {
2071 throw new IllegalStateException(e);
2076 public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
2077 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2079 final LinkAddress la = routeInfo.getDestinationLinkAddress();
2080 final String ifName = routeInfo.getInterface();
2081 final String dst = la.toString();
2082 final String nextHop;
2084 if (routeInfo.hasGateway()) {
2085 nextHop = routeInfo.getGateway().getHostAddress();
2090 mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
2091 } catch (RemoteException | ServiceSpecificException e) {
2092 throw new IllegalStateException(e);
2097 public void setDefaultNetId(int netId) {
2098 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2101 mNetdService.networkSetDefault(netId);
2102 } catch (RemoteException | ServiceSpecificException e) {
2103 throw new IllegalStateException(e);
2108 public void clearDefaultNetId() {
2109 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2112 mNetdService.networkClearDefault();
2113 } catch (RemoteException | ServiceSpecificException e) {
2114 throw new IllegalStateException(e);
2119 public void setNetworkPermission(int netId, int permission) {
2120 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2123 mNetdService.networkSetPermissionForNetwork(netId, permission);
2124 } catch (RemoteException | ServiceSpecificException e) {
2125 throw new IllegalStateException(e);
2130 public void allowProtect(int uid) {
2131 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2134 mNetdService.networkSetProtectAllow(uid);
2135 } catch (RemoteException | ServiceSpecificException e) {
2136 throw new IllegalStateException(e);
2141 public void denyProtect(int uid) {
2142 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2145 mNetdService.networkSetProtectDeny(uid);
2146 } catch (RemoteException | ServiceSpecificException e) {
2147 throw new IllegalStateException(e);
2152 public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
2153 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface);
2155 for (RouteInfo route : routes) {
2156 if (!route.isDefaultRoute()) {
2157 modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, route);
2161 // IPv6 link local should be activated always.
2162 modifyRoute(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID,
2163 new RouteInfo(new IpPrefix("fe80::/64"), null, iface));
2167 public void removeInterfaceFromLocalNetwork(String iface) {
2168 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface);
2172 public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) {
2175 for (RouteInfo route : routes) {
2177 modifyRoute(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, route);
2178 } catch (IllegalStateException e) {
2187 public boolean isNetworkRestricted(int uid) {
2188 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
2189 return isNetworkRestrictedInternal(uid);
2192 private boolean isNetworkRestrictedInternal(int uid) {
2193 synchronized (mRulesLock) {
2194 if (getFirewallChainState(FIREWALL_CHAIN_STANDBY)
2195 && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) {
2196 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode");
2199 if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE)
2200 && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) {
2201 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode");
2204 if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)
2205 && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) {
2206 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
2209 if (mUidRejectOnMetered.get(uid)) {
2210 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
2211 + " in the background");
2214 if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) {
2215 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode");
2222 private void setFirewallChainState(int chain, boolean state) {
2223 synchronized (mRulesLock) {
2224 mFirewallChainStates.put(chain, state);
2228 private boolean getFirewallChainState(int chain) {
2229 synchronized (mRulesLock) {
2230 return mFirewallChainStates.get(chain);
2235 class LocalService extends NetworkManagementInternal {
2237 public boolean isNetworkRestrictedForUid(int uid) {
2238 return isNetworkRestrictedInternal(uid);
2243 Injector getInjector() {
2244 return new Injector();
2249 void setDataSaverMode(boolean dataSaverMode) {
2250 mDataSaverMode = dataSaverMode;
2253 void setFirewallChainState(int chain, boolean state) {
2254 NetworkManagementService.this.setFirewallChainState(chain, state);
2257 void setFirewallRule(int chain, int uid, int rule) {
2258 synchronized (mRulesLock) {
2259 getUidFirewallRulesLR(chain).put(uid, rule);
2263 void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) {
2264 synchronized (mRulesLock) {
2266 mUidRejectOnMetered.put(uid, enable);
2268 mUidAllowOnMetered.put(uid, enable);
2274 synchronized (mRulesLock) {
2275 setDataSaverMode(false);
2276 final int[] chains = {
2277 FIREWALL_CHAIN_DOZABLE,
2278 FIREWALL_CHAIN_STANDBY,
2279 FIREWALL_CHAIN_POWERSAVE
2281 for (int chain : chains) {
2282 setFirewallChainState(chain, false);
2283 getUidFirewallRulesLR(chain).clear();
2285 mUidAllowOnMetered.clear();
2286 mUidRejectOnMetered.clear();