1 /* 2 * Copyright (C) 2022 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.google.android.car.networking.railway; 18 19 import android.content.Context; 20 import android.content.pm.PackageManager; 21 import android.net.EthernetManager; 22 import android.net.EthernetNetworkManagementException; 23 import android.net.EthernetNetworkSpecifier; 24 import android.net.EthernetNetworkUpdateRequest; 25 import android.net.IpConfiguration; 26 import android.net.LinkAddress; 27 import android.net.NetworkCapabilities; 28 import android.net.StaticIpConfiguration; 29 import android.os.OutcomeReceiver; 30 31 import androidx.annotation.Nullable; 32 33 import com.google.common.base.Strings; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 public final class ConfigurationUpdater { 39 private final Context mApplicationContext; 40 private final EthernetManager mEthernetManager; 41 private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback; 42 ConfigurationUpdater(Context applicationContext, OutcomeReceiver<String, EthernetNetworkManagementException> callback)43 public ConfigurationUpdater(Context applicationContext, 44 OutcomeReceiver<String, EthernetNetworkManagementException> callback) { 45 mApplicationContext = applicationContext; 46 mEthernetManager = applicationContext.getSystemService(EthernetManager.class); 47 48 mCallback = callback; 49 } 50 updateNetworkConfiguration(String packageNames, String ipConfigurationText, String networkCapabilitiesText, String interfaceName)51 public void updateNetworkConfiguration(String packageNames, 52 String ipConfigurationText, 53 String networkCapabilitiesText, 54 String interfaceName) 55 throws IllegalArgumentException, PackageManager.NameNotFoundException { 56 57 EthernetNetworkUpdateRequest request = new EthernetNetworkUpdateRequest.Builder() 58 .setIpConfiguration(getIpConfiguration(ipConfigurationText)) 59 .setNetworkCapabilities(getCapabilities( 60 interfaceName, networkCapabilitiesText, packageNames)) 61 .build(); 62 63 mEthernetManager.updateConfiguration(interfaceName, request, 64 mApplicationContext.getMainExecutor(), mCallback); 65 } 66 67 @Nullable getIpConfiguration(String ipConfigurationText)68 private IpConfiguration getIpConfiguration(String ipConfigurationText) { 69 return Strings.isNullOrEmpty(ipConfigurationText) ? null : 70 new IpConfiguration.Builder() 71 .setStaticIpConfiguration(new StaticIpConfiguration.Builder() 72 .setIpAddress(new LinkAddress(ipConfigurationText)).build()) 73 .build(); 74 } 75 76 @Nullable getCapabilities(String iface, String networkCapabilitiesText, String packageNames)77 private NetworkCapabilities getCapabilities(String iface, String networkCapabilitiesText, 78 String packageNames) throws PackageManager.NameNotFoundException { 79 // TODO: Allow for setting package names without capabilities. In this case, the existing 80 // capabilities should be used. 81 if (Strings.isNullOrEmpty(networkCapabilitiesText)) { 82 return null; 83 } 84 85 NetworkCapabilities.Builder networkCapabilitiesBuilder = 86 NetworkCapabilities.Builder.withoutDefaultCapabilities() 87 .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) 88 .setNetworkSpecifier(new EthernetNetworkSpecifier(iface)); 89 90 for (int capability : getCapabilitiesList(networkCapabilitiesText)) { 91 networkCapabilitiesBuilder.addCapability(capability); 92 } 93 94 if (!Strings.isNullOrEmpty(packageNames)) { 95 networkCapabilitiesBuilder.setAllowedUids( 96 UidToPackageNameConverter.convertToUids(mApplicationContext, packageNames)); 97 } 98 99 return networkCapabilitiesBuilder.build(); 100 } 101 getCapabilitiesList(String capabilitiesText)102 private static List<Integer> getCapabilitiesList(String capabilitiesText) 103 throws NumberFormatException { 104 List<Integer> capabilitiesList = new ArrayList<>(); 105 String[] capabilitiesTextArray = capabilitiesText.split(","); 106 for (String capabilityText : capabilitiesTextArray) { 107 capabilitiesList.add(Integer.valueOf(capabilityText)); 108 } 109 return capabilitiesList; 110 } 111 } 112