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.settings.network.ethernet 18 19 import android.content.Context 20 import android.net.EthernetManager 21 import android.net.IpConfiguration 22 import androidx.core.content.ContextCompat 23 24 class EthernetTrackerImpl 25 private constructor(private val context: Context) : 26 EthernetManager.InterfaceStateListener, EthernetTracker { 27 28 private val TAG = "EthernetTracker" 29 30 private val ethernetManager: EthernetManager? = 31 context.getSystemService(EthernetManager::class.java) 32 33 // Maps ethernet interface identifier to EthernetInterface object 34 private val ethernetInterfaces = mutableMapOf<String, EthernetInterface>() 35 private val interfaceListeners = 36 mutableListOf<EthernetTracker.EthernetInterfaceTrackerListener>() 37 getInterfacenull38 override fun getInterface(id: String): EthernetInterface? { 39 return ethernetInterfaces.get(id) 40 } 41 42 override val availableInterfaces: Collection<EthernetInterface> 43 get() = ethernetInterfaces.values 44 registerInterfaceListenernull45 override fun registerInterfaceListener( 46 listener: EthernetTracker.EthernetInterfaceTrackerListener 47 ) { 48 if (interfaceListeners.isEmpty()) { 49 ethernetManager?.addInterfaceStateListener(ContextCompat.getMainExecutor(context), this) 50 } 51 interfaceListeners.add(listener) 52 listener.onInterfaceListChanged(ethernetInterfaces.values.toList()) 53 } 54 unregisterInterfaceListenernull55 override fun unregisterInterfaceListener( 56 listener: EthernetTracker.EthernetInterfaceTrackerListener 57 ) { 58 interfaceListeners.remove(listener) 59 if (interfaceListeners.isEmpty()) { 60 ethernetManager?.removeInterfaceStateListener(this) 61 } 62 } 63 onInterfaceStateChangednull64 override fun onInterfaceStateChanged(id: String, state: Int, role: Int, cfg: IpConfiguration?) { 65 var interfacesChanged = false 66 if (!ethernetInterfaces.contains(id) && state != EthernetManager.STATE_ABSENT) { 67 ethernetInterfaces.put(id, EthernetInterface(context, id)) 68 interfacesChanged = true 69 } else if (ethernetInterfaces.contains(id) && state == EthernetManager.STATE_ABSENT) { 70 ethernetInterfaces.remove(id) 71 interfacesChanged = true 72 } 73 if (interfacesChanged) { 74 for (listener in interfaceListeners) { 75 listener.onInterfaceListChanged(ethernetInterfaces.values.toList()) 76 } 77 } 78 } 79 80 companion object { 81 @Volatile private var INSTANCE: EthernetTrackerImpl? = null 82 83 @JvmStatic getInstancenull84 fun getInstance( 85 context: Context 86 ): EthernetTrackerImpl { 87 return INSTANCE 88 ?: synchronized(this) { 89 val instance = 90 EthernetTrackerImpl(context.applicationContext) 91 INSTANCE = instance 92 instance 93 } 94 } 95 } 96 } 97