1 /* 2 * Copyright (C) 2024 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.tv.mdnsoffloadmanager; 18 19 import android.net.nsd.OffloadEngine; 20 import android.os.Binder; 21 import android.util.Log; 22 23 import androidx.annotation.WorkerThread; 24 25 import java.util.Map; 26 import java.util.HashMap; 27 import java.util.Arrays; 28 import java.util.HexFormat; 29 30 import device.google.atv.mdns_offload.IMdnsOffloadManager.OffloadServiceInfo; 31 32 /** 33 * Offload engine for the NsdManager offload interface. 34 * NsdManager needs at least one different offload engine per interface. 35 * To keep the differentiation on the network interface we use separate NsdManagerOffloadEngine 36 * instances that connect to a single MdnsOffloadManagerService. 37 */ 38 class NsdManagerOffloadEngine implements OffloadEngine { 39 private static final String TAG = NsdManagerOffloadEngine.class.getSimpleName(); 40 41 private final Map<android.net.nsd.OffloadServiceInfo.Key, Integer> mRecordKeys = 42 new HashMap<>(); 43 private final MdnsOffloadManagerService mOffloadManager; 44 private final String mNetworkInterface; 45 private final Binder mClientToken; 46 NsdManagerOffloadEngine(MdnsOffloadManagerService offloadManager, String iface)47 public NsdManagerOffloadEngine(MdnsOffloadManagerService offloadManager, String iface) { 48 mOffloadManager = offloadManager; 49 mNetworkInterface = iface; 50 mClientToken = new Binder("OffloadEngine[%s]".formatted(iface)); 51 } 52 53 @WorkerThread 54 @Override onOffloadServiceUpdated(android.net.nsd.OffloadServiceInfo info)55 public void onOffloadServiceUpdated(android.net.nsd.OffloadServiceInfo info) { 56 OffloadServiceInfo internalInfo = new OffloadServiceInfo(); 57 internalInfo.serviceName = info.getKey().getServiceName(); 58 internalInfo.serviceType = info.getKey().getServiceType(); 59 internalInfo.deviceHostName = info.getHostname(); 60 internalInfo.rawOffloadPacket = info.getOffloadPayload(); 61 62 // DO NOT SUBMIT - workaround http://b/323169340 63 Log.e(TAG, "eGVB: onOffloadServiceUpdated %s".formatted(Arrays.toString(info.getOffloadPayload()))); 64 65 int recordKey = mOffloadManager 66 .addProtocolResponses(mNetworkInterface, internalInfo, mClientToken); 67 68 mRecordKeys.put(info.getKey(), recordKey); 69 } 70 71 @WorkerThread 72 @Override onOffloadServiceRemoved(android.net.nsd.OffloadServiceInfo info)73 public void onOffloadServiceRemoved(android.net.nsd.OffloadServiceInfo info) { 74 Integer recordKey = mRecordKeys.remove(info.getKey()); 75 if (recordKey == null) { 76 Log.e(TAG, "Unknown OffloadService key %s".formatted(info.getKey())); 77 return; 78 } 79 mOffloadManager.removeProtocolResponses(recordKey, mClientToken); 80 } 81 82 /** 83 * Clean up any dangling protocol responses created by NsdManager for this interface. 84 */ 85 @WorkerThread clearOffloadServices()86 void clearOffloadServices() { 87 for (Integer recordKey : mRecordKeys.values()) { 88 mOffloadManager.removeProtocolResponses(recordKey, mClientToken); 89 } 90 mRecordKeys.clear(); 91 } 92 } 93