• 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 package android.net.apf;
17 
18 import android.annotation.NonNull;
19 import android.annotation.RequiresApi;
20 import android.net.nsd.NsdManager;
21 import android.net.nsd.OffloadEngine;
22 import android.net.nsd.OffloadServiceInfo;
23 import android.os.Build;
24 import android.os.Handler;
25 import android.util.Log;
26 
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * APF offload engine implementation for managing mDNS offloads.
33  */
34 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
35 public class ApfMdnsOffloadEngine implements OffloadEngine {
36 
37     private static final String TAG = ApfMdnsOffloadEngine.class.getSimpleName();
38 
39     /**
40      * Callback interface for receiving notifications about offload rule updates.
41      */
42     public interface Callback {
43         /**
44          * Called when the offload rules are updated.
45          * <p>
46          * This method is called on the handler thread.
47          *
48          * @param allRules The updated list of MDNS offload rules.
49          */
onOffloadRulesUpdated(@onNull List<MdnsOffloadRule> allRules)50         void onOffloadRulesUpdated(@NonNull List<MdnsOffloadRule> allRules);
51     }
52 
53     @NonNull
54     private final List<OffloadServiceInfo> mOffloadServiceInfos = new ArrayList<>();
55     @NonNull
56     private final String mInterfaceName;
57     @NonNull
58     private final Handler mHandler;
59     @NonNull
60     private final NsdManager mNsdManager;
61     @NonNull
62     private final Callback mCallback;
63 
64     /**
65      * Constructor for ApfOffloadEngine.
66      */
ApfMdnsOffloadEngine(@onNull String interfaceName, @NonNull Handler handler, @NonNull NsdManager nsdManager, @NonNull Callback callback)67     public ApfMdnsOffloadEngine(@NonNull String interfaceName, @NonNull Handler handler,
68             @NonNull NsdManager nsdManager, @NonNull Callback callback) {
69         mInterfaceName = interfaceName;
70         mHandler = handler;
71         mNsdManager = nsdManager;
72         mCallback = callback;
73     }
74 
75     @Override
onOffloadServiceUpdated(@onNull OffloadServiceInfo info)76     public void onOffloadServiceUpdated(@NonNull OffloadServiceInfo info) {
77         handleOffloadServiceUpdated(info, false /* isRemoved */);
78     }
79 
80     @Override
onOffloadServiceRemoved(@onNull OffloadServiceInfo info)81     public void onOffloadServiceRemoved(@NonNull OffloadServiceInfo info) {
82         handleOffloadServiceUpdated(info, true /* isRemoved */);
83     }
84 
handleOffloadServiceUpdated(@onNull OffloadServiceInfo info, boolean isRemoved)85     private void handleOffloadServiceUpdated(@NonNull OffloadServiceInfo info, boolean isRemoved) {
86         if (isRemoved) {
87             mOffloadServiceInfos.removeIf(i -> i.getKey().equals(info.getKey()));
88         } else {
89             mOffloadServiceInfos.removeIf(i -> i.getKey().equals(info.getKey()));
90             mOffloadServiceInfos.add(info);
91         }
92         try {
93             List<MdnsOffloadRule> offloadRules = ApfMdnsUtils.extractOffloadReplyRule(
94                     mOffloadServiceInfos);
95             mCallback.onOffloadRulesUpdated(offloadRules);
96         } catch (IOException e) {
97             Log.e(TAG, "Failed to extract offload reply rule", e);
98         }
99     }
100 
101     /**
102      * Registers the offload engine with the NsdManager.
103      */
registerOffloadEngine()104     public void registerOffloadEngine() {
105         mNsdManager.registerOffloadEngine(mInterfaceName, OFFLOAD_TYPE_REPLY,
106                 OFFLOAD_CAPABILITY_BYPASS_MULTICAST_LOCK, mHandler::post, this);
107     }
108 
109     /**
110      * Unregisters the offload engine with the NsdManager.
111      */
unregisterOffloadEngine()112     public void unregisterOffloadEngine() {
113         mNsdManager.unregisterOffloadEngine(this);
114         mOffloadServiceInfos.clear();
115     }
116 }
117