• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 com.android.server;
18 
19 import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
20 import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
21 import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
22 
23 import static com.android.net.module.util.DeviceConfigUtils.getResBooleanConfig;
24 import static com.android.server.util.PermissionUtil.checkDumpPermission;
25 
26 import android.app.Service;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.net.IIpMemoryStore;
30 import android.net.IIpMemoryStoreCallbacks;
31 import android.net.INetd;
32 import android.net.INetworkMonitor;
33 import android.net.INetworkMonitorCallbacks;
34 import android.net.INetworkStackConnector;
35 import android.net.INetworkStackStatusCallback;
36 import android.net.LinkProperties;
37 import android.net.Network;
38 import android.net.NetworkCapabilities;
39 import android.net.PrivateDnsConfigParcel;
40 import android.net.dhcp.DhcpServer;
41 import android.net.dhcp.DhcpServingParams;
42 import android.net.dhcp.DhcpServingParamsParcel;
43 import android.net.dhcp.IDhcpServerCallbacks;
44 import android.net.ip.IIpClientCallbacks;
45 import android.net.ip.IpClient;
46 import android.net.networkstack.aidl.NetworkMonitorParameters;
47 import android.net.shared.PrivateDnsConfig;
48 import android.os.Build;
49 import android.os.HandlerThread;
50 import android.os.IBinder;
51 import android.os.Looper;
52 import android.os.RemoteException;
53 import android.text.TextUtils;
54 import android.util.ArraySet;
55 
56 import androidx.annotation.NonNull;
57 import androidx.annotation.Nullable;
58 import androidx.annotation.VisibleForTesting;
59 
60 import com.android.internal.annotations.GuardedBy;
61 import com.android.internal.util.IndentingPrintWriter;
62 import com.android.net.module.util.SharedLog;
63 import com.android.networkstack.NetworkStackNotifier;
64 import com.android.networkstack.R;
65 import com.android.networkstack.apishim.common.ShimUtils;
66 import com.android.networkstack.ipmemorystore.IpMemoryStoreService;
67 import com.android.server.connectivity.NetworkMonitor;
68 import com.android.server.util.PermissionUtil;
69 
70 import java.io.FileDescriptor;
71 import java.io.PrintWriter;
72 import java.lang.ref.WeakReference;
73 import java.util.ArrayDeque;
74 import java.util.ArrayList;
75 import java.util.Collection;
76 import java.util.Collections;
77 import java.util.Comparator;
78 import java.util.HashSet;
79 import java.util.Iterator;
80 import java.util.List;
81 import java.util.Objects;
82 import java.util.SortedSet;
83 import java.util.TreeSet;
84 
85 /**
86  * Android service used to start the network stack when bound to via an intent.
87  *
88  * <p>The service returns a binder for the system server to communicate with the network stack.
89  */
90 public class NetworkStackService extends Service {
91     private static final String TAG = NetworkStackService.class.getSimpleName();
92     private static NetworkStackConnector sConnector;
93 
94     /**
95      * Create a binder connector for the system server to communicate with the network stack.
96      *
97      * <p>On platforms where the network stack runs in the system server process, this method may
98      * be called directly instead of obtaining the connector by binding to the service.
99      */
makeConnector(Context context)100     public static synchronized IBinder makeConnector(Context context) {
101         if (sConnector == null) {
102             sConnector = new NetworkStackConnector(context);
103         }
104         return sConnector;
105     }
106 
107     @NonNull
108     @Override
onBind(Intent intent)109     public IBinder onBind(Intent intent) {
110         return makeConnector(this);
111     }
112 
113     /**
114      * An interface for internal clients of the network stack service that can return
115      * or create inline instances of the service it manages.
116      */
117     public interface NetworkStackServiceManager {
118         /**
119          * Get an instance of the IpMemoryStoreService.
120          */
getIpMemoryStoreService()121         IIpMemoryStore getIpMemoryStoreService();
122 
123         /**
124          * Get an instance of the NetworkNotifier.
125          */
getNotifier()126         NetworkStackNotifier getNotifier();
127     }
128 
129     /**
130      * Permission checking dependency of the connector, useful for testing.
131      */
132     public static class PermissionChecker {
133         /**
134          * @see PermissionUtil#enforceNetworkStackCallingPermission()
135          */
enforceNetworkStackCallingPermission()136         public void enforceNetworkStackCallingPermission() {
137             PermissionUtil.enforceNetworkStackCallingPermission();
138         }
139     }
140 
141     /**
142      * Dependencies of {@link NetworkStackConnector}, useful for testing.
143      */
144     public static class Dependencies {
145         /** @see IpMemoryStoreService */
146         @NonNull
makeIpMemoryStoreService(@onNull Context context)147         public IpMemoryStoreService makeIpMemoryStoreService(@NonNull Context context) {
148             return new IpMemoryStoreService(context);
149         }
150 
151         /** @see NetworkStackNotifier */
152         @NonNull
makeNotifier(@onNull Context context, @NonNull Looper looper)153         public NetworkStackNotifier makeNotifier(@NonNull Context context, @NonNull Looper looper) {
154             return new NetworkStackNotifier(context, looper);
155         }
156 
157         /** @see DhcpServer */
158         @NonNull
makeDhcpServer(@onNull Context context, @NonNull String ifName, @NonNull DhcpServingParams params, @NonNull SharedLog log)159         public DhcpServer makeDhcpServer(@NonNull Context context, @NonNull String ifName,
160                 @NonNull DhcpServingParams params, @NonNull SharedLog log) {
161             return new DhcpServer(context, ifName, params, log);
162         }
163 
164         /** @see NetworkMonitor */
165         @NonNull
makeNetworkMonitor(@onNull Context context, @NonNull INetworkMonitorCallbacks cb, @NonNull Network network, @NonNull SharedLog log, @NonNull NetworkStackServiceManager nsServiceManager)166         public NetworkMonitor makeNetworkMonitor(@NonNull Context context,
167                 @NonNull INetworkMonitorCallbacks cb, @NonNull Network network,
168                 @NonNull SharedLog log, @NonNull NetworkStackServiceManager nsServiceManager) {
169             return new NetworkMonitor(context, cb, network, log, nsServiceManager);
170         }
171 
172         /** @see IpClient */
173         @NonNull
makeIpClient(@onNull Context context, @NonNull String ifName, @NonNull IIpClientCallbacks cb, @NonNull NetworkObserverRegistry observerRegistry, @NonNull NetworkStackServiceManager nsServiceManager)174         public IpClient makeIpClient(@NonNull Context context, @NonNull String ifName,
175                 @NonNull IIpClientCallbacks cb, @NonNull NetworkObserverRegistry observerRegistry,
176                 @NonNull NetworkStackServiceManager nsServiceManager) {
177             return new IpClient(context, ifName, cb, observerRegistry, nsServiceManager);
178         }
179     }
180 
181     /**
182      * Connector implementing INetworkStackConnector for clients.
183      */
184     @VisibleForTesting
185     public static class NetworkStackConnector extends INetworkStackConnector.Stub
186             implements NetworkStackServiceManager {
187         private static final int NUM_VALIDATION_LOG_LINES = 20;
188         private final Context mContext;
189         private final PermissionChecker mPermChecker;
190         private final Dependencies mDeps;
191         private final INetd mNetd;
192         private final NetworkObserverRegistry mObserverRegistry;
193         @GuardedBy("mIpClients")
194         private final ArrayList<WeakReference<IpClient>> mIpClients = new ArrayList<>();
195         private final IpMemoryStoreService mIpMemoryStoreService;
196         @Nullable
197         private final NetworkStackNotifier mNotifier;
198 
199         private static final int MAX_VALIDATION_LOGS = 10;
200         @GuardedBy("mValidationLogs")
201         private final ArrayDeque<SharedLog> mValidationLogs = new ArrayDeque<>(MAX_VALIDATION_LOGS);
202 
203         private static final String DUMPSYS_ARG_VERSION = "version";
204 
205         private static final String AIDL_KEY_NETWORKSTACK = "networkstack";
206         private static final String AIDL_KEY_IPMEMORYSTORE = "ipmemorystore";
207         private static final String AIDL_KEY_NETD = "netd";
208 
209         private static final int VERSION_UNKNOWN = -1;
210         private static final String HASH_UNKNOWN = "unknown";
211 
212         /**
213          * Versions of the AIDL interfaces observed by the network stack, in other words versions
214          * that the framework and other modules communicating with the network stack are using.
215          * The map may hold multiple values as the interface is used by modules with different
216          * versions.
217          */
218         @GuardedBy("mFrameworkAidlVersions")
219         private final ArraySet<AidlVersion> mAidlVersions = new ArraySet<>();
220 
221         private static final class AidlVersion implements Comparable<AidlVersion> {
222             @NonNull
223             final String mKey;
224             final int mVersion;
225             @NonNull
226             final String mHash;
227 
228             private static final Comparator<AidlVersion> COMPARATOR =
229                     Comparator.comparing((AidlVersion v) -> v.mKey)
230                             .thenComparingInt(v -> v.mVersion)
231                             .thenComparing(v -> v.mHash, String::compareTo);
232 
AidlVersion(@onNull String key, int version, @NonNull String hash)233             AidlVersion(@NonNull String key, int version, @NonNull String hash) {
234                 mKey = key;
235                 mVersion = version;
236                 mHash = hash;
237             }
238 
239             @Override
hashCode()240             public int hashCode() {
241                 return Objects.hash(mVersion, mHash);
242             }
243 
244             @Override
equals(@ullable Object obj)245             public boolean equals(@Nullable Object obj) {
246                 if (!(obj instanceof AidlVersion)) return false;
247                 final AidlVersion other = (AidlVersion) obj;
248                 return Objects.equals(mKey, other.mKey)
249                         && Objects.equals(mVersion, other.mVersion)
250                         && Objects.equals(mHash, other.mHash);
251             }
252 
253             @NonNull
254             @Override
toString()255             public String toString() {
256                 // Use a format that can be easily parsed by tests for the version
257                 return String.format("%s:%s:%s", mKey, mVersion, mHash);
258             }
259 
260             @Override
compareTo(AidlVersion o)261             public int compareTo(AidlVersion o) {
262                 return COMPARATOR.compare(this, o);
263             }
264         }
265 
addValidationLogs(Network network, String name)266         private SharedLog addValidationLogs(Network network, String name) {
267             final SharedLog log = new SharedLog(NUM_VALIDATION_LOG_LINES, network + " - " + name);
268             synchronized (mValidationLogs) {
269                 while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
270                     mValidationLogs.removeLast();
271                 }
272                 mValidationLogs.addFirst(log);
273             }
274             return log;
275         }
276 
NetworkStackConnector(@onNull Context context)277         NetworkStackConnector(@NonNull Context context) {
278             this(context, new PermissionChecker(), new Dependencies());
279         }
280 
281         @VisibleForTesting
NetworkStackConnector( @onNull Context context, @NonNull PermissionChecker permChecker, @NonNull Dependencies deps)282         public NetworkStackConnector(
283                 @NonNull Context context, @NonNull PermissionChecker permChecker,
284                 @NonNull Dependencies deps) {
285             mContext = context;
286             mPermChecker = permChecker;
287             mDeps = deps;
288             mNetd = INetd.Stub.asInterface(
289                     (IBinder) context.getSystemService(Context.NETD_SERVICE));
290             mObserverRegistry = new NetworkObserverRegistry();
291             mIpMemoryStoreService = mDeps.makeIpMemoryStoreService(context);
292             // NetworkStackNotifier only shows notifications relevant for API level > Q
293             if (ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)) {
294                 final HandlerThread notifierThread = new HandlerThread(
295                         NetworkStackNotifier.class.getSimpleName());
296                 notifierThread.start();
297                 mNotifier = mDeps.makeNotifier(context, notifierThread.getLooper());
298             } else {
299                 mNotifier = null;
300             }
301 
302             int netdVersion;
303             String netdHash;
304             try {
305                 netdVersion = mNetd.getInterfaceVersion();
306                 netdHash = mNetd.getInterfaceHash();
307             } catch (RemoteException e) {
308                 mLog.e("Error obtaining INetd version", e);
309                 netdVersion = VERSION_UNKNOWN;
310                 netdHash = HASH_UNKNOWN;
311             }
312             updateNetdAidlVersion(netdVersion, netdHash);
313 
314             try {
315                 mObserverRegistry.register(mNetd);
316             } catch (RemoteException e) {
317                 mLog.e("Error registering observer on Netd", e);
318             }
319         }
320 
updateNetdAidlVersion(final int version, final String hash)321         private void updateNetdAidlVersion(final int version, final String hash) {
322             synchronized (mAidlVersions) {
323                 mAidlVersions.add(new AidlVersion(AIDL_KEY_NETD, version, hash));
324             }
325         }
326 
updateNetworkStackAidlVersion(final int version, final String hash)327         private void updateNetworkStackAidlVersion(final int version, final String hash) {
328             synchronized (mAidlVersions) {
329                 mAidlVersions.add(new AidlVersion(AIDL_KEY_NETWORKSTACK, version, hash));
330             }
331         }
332 
updateIpMemoryStoreAidlVersion(final int version, final String hash)333         private void updateIpMemoryStoreAidlVersion(final int version, final String hash) {
334             synchronized (mAidlVersions) {
335                 mAidlVersions.add(new AidlVersion(AIDL_KEY_IPMEMORYSTORE, version, hash));
336             }
337         }
338 
339         @NonNull
340         private final SharedLog mLog = new SharedLog(TAG);
341 
342         @Override
makeDhcpServer(@onNull String ifName, @NonNull DhcpServingParamsParcel params, @NonNull IDhcpServerCallbacks cb)343         public void makeDhcpServer(@NonNull String ifName, @NonNull DhcpServingParamsParcel params,
344                 @NonNull IDhcpServerCallbacks cb) throws RemoteException {
345             mPermChecker.enforceNetworkStackCallingPermission();
346             updateNetworkStackAidlVersion(cb.getInterfaceVersion(), cb.getInterfaceHash());
347             final DhcpServer server;
348             try {
349                 server = mDeps.makeDhcpServer(
350                         mContext,
351                         ifName,
352                         DhcpServingParams.fromParcelableObject(params),
353                         mLog.forSubComponent(ifName + ".DHCP"));
354             } catch (DhcpServingParams.InvalidParameterException e) {
355                 mLog.e("Invalid DhcpServingParams", e);
356                 cb.onDhcpServerCreated(STATUS_INVALID_ARGUMENT, null);
357                 return;
358             } catch (Exception e) {
359                 mLog.e("Unknown error starting DhcpServer", e);
360                 cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
361                 return;
362             }
363             cb.onDhcpServerCreated(STATUS_SUCCESS, server.makeConnector());
364         }
365 
366         @Override
makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)367         public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)
368                 throws RemoteException {
369             mPermChecker.enforceNetworkStackCallingPermission();
370             updateNetworkStackAidlVersion(cb.getInterfaceVersion(), cb.getInterfaceHash());
371             final SharedLog log = addValidationLogs(network, name);
372             final NetworkMonitor nm = mDeps.makeNetworkMonitor(mContext, cb, network, log, this);
373             cb.onNetworkMonitorCreated(new NetworkMonitorConnector(nm, mPermChecker));
374         }
375 
376         @Override
makeIpClient(String ifName, IIpClientCallbacks cb)377         public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException {
378             mPermChecker.enforceNetworkStackCallingPermission();
379             updateNetworkStackAidlVersion(cb.getInterfaceVersion(), cb.getInterfaceHash());
380             final IpClient ipClient = mDeps.makeIpClient(
381                     mContext, ifName, cb, mObserverRegistry, this);
382 
383             synchronized (mIpClients) {
384                 final Iterator<WeakReference<IpClient>> it = mIpClients.iterator();
385                 while (it.hasNext()) {
386                     final IpClient ipc = it.next().get();
387                     if (ipc == null) {
388                         it.remove();
389                     }
390                 }
391                 mIpClients.add(new WeakReference<>(ipClient));
392             }
393 
394             cb.onIpClientCreated(ipClient.makeConnector());
395         }
396 
397         @Override
getIpMemoryStoreService()398         public IIpMemoryStore getIpMemoryStoreService() {
399             return mIpMemoryStoreService;
400         }
401 
402         @Override
getNotifier()403         public NetworkStackNotifier getNotifier() {
404             return mNotifier;
405         }
406 
407         @Override
fetchIpMemoryStore(@onNull final IIpMemoryStoreCallbacks cb)408         public void fetchIpMemoryStore(@NonNull final IIpMemoryStoreCallbacks cb)
409                 throws RemoteException {
410             mPermChecker.enforceNetworkStackCallingPermission();
411             updateIpMemoryStoreAidlVersion(cb.getInterfaceVersion(), cb.getInterfaceHash());
412             cb.onIpMemoryStoreFetched(mIpMemoryStoreService);
413         }
414 
415         @Override
allowTestUid(int uid, @Nullable INetworkStackStatusCallback cb)416         public void allowTestUid(int uid, @Nullable INetworkStackStatusCallback cb)
417                 throws RemoteException {
418             // setTestUid does its own permission checks
419             PermissionUtil.setTestUid(mContext, uid);
420             mLog.i("Allowing test uid " + uid);
421             if (cb != null) cb.onStatusAvailable(0);
422         }
423 
424         @Override @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
dump(@onNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args)425         public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
426                 @Nullable String[] args) {
427             checkDumpPermission();
428 
429             final IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
430             pw.println("NetworkStack version:");
431             dumpVersion(pw);
432             pw.println();
433 
434             if (args != null && args.length >= 1 && DUMPSYS_ARG_VERSION.equals(args[0])) {
435                 return;
436             }
437 
438             pw.println("NetworkStack logs:");
439             mLog.dump(fd, pw, args);
440 
441             // Dump full IpClient logs for non-GCed clients
442             pw.println();
443             pw.println("Recently active IpClient logs:");
444             final ArrayList<IpClient> ipClients = new ArrayList<>();
445             final HashSet<String> dumpedIpClientIfaces = new HashSet<>();
446             synchronized (mIpClients) {
447                 for (WeakReference<IpClient> ipcRef : mIpClients) {
448                     final IpClient ipc = ipcRef.get();
449                     if (ipc != null) {
450                         ipClients.add(ipc);
451                     }
452                 }
453             }
454 
455             for (IpClient ipc : ipClients) {
456                 pw.println(ipc.getName());
457                 pw.increaseIndent();
458                 ipc.dump(fd, pw, args);
459                 pw.decreaseIndent();
460                 dumpedIpClientIfaces.add(ipc.getInterfaceName());
461             }
462 
463             // State machine and connectivity metrics logs are kept for GCed IpClients
464             pw.println();
465             pw.println("Other IpClient logs:");
466             IpClient.dumpAllLogs(fout, dumpedIpClientIfaces);
467 
468             pw.println();
469             pw.println("Validation logs (most recent first):");
470             synchronized (mValidationLogs) {
471                 for (SharedLog p : mValidationLogs) {
472                     pw.println(p.getTag());
473                     pw.increaseIndent();
474                     p.dump(fd, pw, args);
475                     pw.decreaseIndent();
476                 }
477             }
478 
479             pw.println();
480             pw.print("useNeighborResource: ");
481             pw.println(getResBooleanConfig(mContext,
482                     R.bool.config_no_sim_card_uses_neighbor_mcc, false));
483         }
484 
485         /**
486          * Dump version information of the module and detected system version.
487          */
dumpVersion(@onNull PrintWriter fout)488         private void dumpVersion(@NonNull PrintWriter fout) {
489             if (!ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)) {
490                 dumpVersionNumberOnly(fout);
491                 return;
492             }
493 
494             fout.println("LocalInterface:" + this.VERSION + ":" + this.HASH);
495             synchronized (mAidlVersions) {
496                 // Sort versions for deterministic order in output
497                 for (AidlVersion version : sortVersions(mAidlVersions)) {
498                     fout.println(version);
499                 }
500             }
501         }
502 
sortVersions(Collection<AidlVersion> versions)503         private List<AidlVersion> sortVersions(Collection<AidlVersion> versions) {
504             final List<AidlVersion> sorted = new ArrayList<>(versions);
505             Collections.sort(sorted);
506             return sorted;
507         }
508 
509         /**
510          * Legacy version of dumpVersion, only used for Q, as only the interface version number
511          * was used in Q.
512          *
513          * <p>Q behavior needs to be preserved as conformance tests for Q still expect this format.
514          * Once all conformance test suites are updated to expect the new format even on Q devices,
515          * this can be removed.
516          */
dumpVersionNumberOnly(@onNull PrintWriter fout)517         private void dumpVersionNumberOnly(@NonNull PrintWriter fout) {
518             fout.println("NetworkStackConnector: " + this.VERSION);
519             final SortedSet<Integer> systemServerVersions = new TreeSet<>();
520             int netdVersion = VERSION_UNKNOWN;
521             synchronized (mAidlVersions) {
522                 for (AidlVersion version : mAidlVersions) {
523                     switch (version.mKey) {
524                         case AIDL_KEY_IPMEMORYSTORE:
525                         case AIDL_KEY_NETWORKSTACK:
526                             systemServerVersions.add(version.mVersion);
527                             break;
528                         case AIDL_KEY_NETD:
529                             netdVersion = version.mVersion;
530                             break;
531                         default:
532                             break;
533                     }
534                 }
535             }
536             // TreeSet.toString is formatted as [a, b], but Q used ArraySet.toString formatted as
537             // {a, b}. ArraySet does not have guaranteed ordering, which was not a problem in Q
538             // when only one interface number was expected (and there was no unit test relying on
539             // the ordering).
540             fout.println("SystemServer: {" + TextUtils.join(", ", systemServerVersions) + "}");
541             fout.println("Netd: " + netdVersion);
542         }
543 
544         /**
545          * Get the version of the AIDL interface.
546          */
547         @Override
getInterfaceVersion()548         public int getInterfaceVersion() {
549             return this.VERSION;
550         }
551 
552         @Override
getInterfaceHash()553         public String getInterfaceHash() {
554             return this.HASH;
555         }
556     }
557 
558     /**
559      * Proxy for {@link NetworkMonitor} that implements {@link INetworkMonitor}.
560      */
561     @VisibleForTesting
562     public static class NetworkMonitorConnector extends INetworkMonitor.Stub {
563         @NonNull
564         private final NetworkMonitor mNm;
565         @NonNull
566         private final PermissionChecker mPermChecker;
567 
NetworkMonitorConnector(@onNull NetworkMonitor nm, @NonNull PermissionChecker permChecker)568         public NetworkMonitorConnector(@NonNull NetworkMonitor nm,
569                 @NonNull PermissionChecker permChecker) {
570             mNm = nm;
571             mPermChecker = permChecker;
572         }
573 
574         @Override
start()575         public void start() {
576             mPermChecker.enforceNetworkStackCallingPermission();
577             mNm.start();
578         }
579 
580         @Override
launchCaptivePortalApp()581         public void launchCaptivePortalApp() {
582             mPermChecker.enforceNetworkStackCallingPermission();
583             mNm.launchCaptivePortalApp();
584         }
585 
586         @Override
notifyCaptivePortalAppFinished(int response)587         public void notifyCaptivePortalAppFinished(int response) {
588             mPermChecker.enforceNetworkStackCallingPermission();
589             mNm.notifyCaptivePortalAppFinished(response);
590         }
591 
592         @Override
setAcceptPartialConnectivity()593         public void setAcceptPartialConnectivity() {
594             mPermChecker.enforceNetworkStackCallingPermission();
595             mNm.setAcceptPartialConnectivity();
596         }
597 
598         @Override
forceReevaluation(int uid)599         public void forceReevaluation(int uid) {
600             mPermChecker.enforceNetworkStackCallingPermission();
601             mNm.forceReevaluation(uid);
602         }
603 
604         @Override
notifyPrivateDnsChanged(PrivateDnsConfigParcel config)605         public void notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
606             mPermChecker.enforceNetworkStackCallingPermission();
607             mNm.notifyPrivateDnsSettingsChanged(PrivateDnsConfig.fromParcel(config));
608         }
609 
610         @Override
notifyDnsResponse(int returnCode)611         public void notifyDnsResponse(int returnCode) {
612             mPermChecker.enforceNetworkStackCallingPermission();
613             mNm.notifyDnsResponse(returnCode);
614         }
615 
616         /**
617          * Send a notification to NetworkMonitor indicating that the network is now connected.
618          * @Deprecated use notifyNetworkConnectedParcel, which also passes the NetworkAgentConfig.
619          */
620         @Override
notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc)621         public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
622             mPermChecker.enforceNetworkStackCallingPermission();
623             mNm.notifyNetworkConnected(lp, nc);
624         }
625 
626         /**
627          * Send a notification to NetworkMonitor indicating that the network is now connected.
628          */
629         @Override
notifyNetworkConnectedParcel(NetworkMonitorParameters params)630         public void notifyNetworkConnectedParcel(NetworkMonitorParameters params) {
631             mPermChecker.enforceNetworkStackCallingPermission();
632             mNm.notifyNetworkConnectedParcel(params);
633         }
634 
635         @Override
notifyNetworkDisconnected()636         public void notifyNetworkDisconnected() {
637             mPermChecker.enforceNetworkStackCallingPermission();
638             mNm.notifyNetworkDisconnected();
639         }
640 
641         @Override
notifyLinkPropertiesChanged(LinkProperties lp)642         public void notifyLinkPropertiesChanged(LinkProperties lp) {
643             mPermChecker.enforceNetworkStackCallingPermission();
644             mNm.notifyLinkPropertiesChanged(lp);
645         }
646 
647         @Override
notifyNetworkCapabilitiesChanged(NetworkCapabilities nc)648         public void notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
649             mPermChecker.enforceNetworkStackCallingPermission();
650             mNm.notifyNetworkCapabilitiesChanged(nc);
651         }
652 
653         @Override
getInterfaceVersion()654         public int getInterfaceVersion() {
655             return this.VERSION;
656         }
657 
658         @Override
getInterfaceHash()659         public String getInterfaceHash() {
660             return this.HASH;
661         }
662     }
663 }
664