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