• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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.connectivity;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.system.Os;
22 import android.util.ArrayMap;
23 import android.util.Log;
24 
25 import com.android.internal.annotations.VisibleForTesting;
26 import com.android.server.BpfNetMaps;
27 
28 import java.util.Map;
29 
30 /**
31  * InterfaceTracker is responsible for providing interface mapping and tracking.
32  * @hide
33  */
34 public class InterfaceTracker {
35     static {
36         if (BpfNetMaps.isAtLeast25Q2()) {
37             System.loadLibrary("service-connectivity");
38         }
39     }
40     private static final String TAG = "InterfaceTracker";
41     private final Dependencies mDeps;
42     private final Map<String, Integer> mInterfaceMap;
43 
InterfaceTracker(final Context context)44     public InterfaceTracker(final Context context) {
45         this(context, new Dependencies());
46     }
47 
48     @VisibleForTesting
InterfaceTracker(final Context context, final Dependencies deps)49     public InterfaceTracker(final Context context, final Dependencies deps) {
50         this.mInterfaceMap = new ArrayMap<>();
51         this.mDeps = deps;
52     }
53 
54     /**
55      * To add interface to tracking
56      * @param interfaceName name of interface added.
57      */
addInterface(@ullable final String interfaceName)58     public void addInterface(@Nullable final String interfaceName) {
59         final int interfaceIndex;
60         if (interfaceName == null) {
61             interfaceIndex = 0;
62         } else {
63             interfaceIndex = mDeps.getIfIndex(interfaceName);
64         }
65         if (interfaceIndex == 0) {
66             Log.e(TAG, "Failed to get interface index for " + interfaceName);
67             return;
68         }
69         synchronized (mInterfaceMap) {
70             mInterfaceMap.put(interfaceName, interfaceIndex);
71         }
72     }
73 
74     /**
75      * To remove interface from tracking
76      * @param interfaceName name of interface removed.
77      * @return true if the value was present and now removed.
78      */
removeInterface(@ullable final String interfaceName)79     public boolean removeInterface(@Nullable final String interfaceName) {
80         if (interfaceName == null) return false;
81         synchronized (mInterfaceMap) {
82             return mInterfaceMap.remove(interfaceName) != null;
83         }
84     }
85 
86     /**
87      * Get interface index from interface name.
88      * @param interfaceName name of interface
89      * @return interface index for given interface name or 0 if interface is not found.
90      */
getInterfaceIndex(@ullable final String interfaceName)91     public int getInterfaceIndex(@Nullable final String interfaceName) {
92         final int interfaceIndex;
93         if (interfaceName != null) {
94             synchronized (mInterfaceMap) {
95                 interfaceIndex = mInterfaceMap.getOrDefault(interfaceName, 0);
96             }
97         } else {
98             interfaceIndex = 0;
99         }
100         return interfaceIndex;
101     }
102 
103     /**
104      * Dependencies of InterfaceTracker, for injection in tests.
105      */
106     @VisibleForTesting
107     public static class Dependencies {
108         /**
109          * Get interface index.
110          */
getIfIndex(final String ifName)111         public int getIfIndex(final String ifName) {
112             return Os.if_nametoindex(ifName);
113         }
114 
115         /**
116          * Get interface name
117          */
getIfName(final int ifIndex)118         public String getIfName(final int ifIndex) {
119             return Os.if_indextoname(ifIndex);
120         }
121 
122     }
123 }
124