• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.tv.mdnsoffloadmanager;
2 
3 import android.util.Log;
4 
5 import androidx.annotation.NonNull;
6 import androidx.annotation.WorkerThread;
7 
8 import java.io.PrintWriter;
9 import java.util.Collection;
10 import java.util.Collections;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.Set;
14 
15 @WorkerThread
16 public class InterfaceOffloadManager {
17 
18     private static final String TAG = InterfaceOffloadManager.class.getSimpleName();
19 
20     private final String mNetworkInterface;
21     private final OffloadIntentStore mOffloadIntentStore;
22     private final OffloadWriter mOffloadWriter;
23     private final Set<Integer> mCurrentOffloadKeys = new HashSet<>();
24     private final Set<String> mCurrentPassthroughQNames = new HashSet<>();
25     private boolean mIsNetworkAvailable = false;
26 
InterfaceOffloadManager( @onNull String networkInterface, @NonNull OffloadIntentStore offloadIntentStore, @NonNull OffloadWriter offloadWriter)27     InterfaceOffloadManager(
28             @NonNull String networkInterface,
29             @NonNull OffloadIntentStore offloadIntentStore,
30             @NonNull OffloadWriter offloadWriter) {
31         mNetworkInterface = networkInterface;
32         mOffloadIntentStore = offloadIntentStore;
33         mOffloadWriter = offloadWriter;
34     }
35 
onVendorServiceConnected()36     void onVendorServiceConnected() {
37         refreshProtocolResponses();
38         refreshPassthroughList();
39     }
40 
onAppIdAllowlistUpdated()41     void onAppIdAllowlistUpdated() {
42         refreshProtocolResponses();
43         refreshPassthroughList();
44     }
45 
onNetworkAvailable()46     void onNetworkAvailable() {
47         String msg = "Network interface {" + mNetworkInterface + "} is connected." +
48                 " Offloading all stored data.";
49         Log.d(TAG, msg);
50         mIsNetworkAvailable = true;
51         refreshProtocolResponses();
52         refreshPassthroughList();
53     }
54 
onNetworkLost()55     void onNetworkLost() {
56         String msg = "Network interface {" + mNetworkInterface + "} was disconnected."
57                 + " Clearing all associated data.";
58         Log.d(TAG, msg);
59         mIsNetworkAvailable = false;
60         clearProtocolResponses();
61         clearPassthroughList();
62     }
63 
onVendorServiceDisconnected()64     void onVendorServiceDisconnected() {
65         mCurrentOffloadKeys.clear();
66         mCurrentPassthroughQNames.clear();
67     }
68 
refreshProtocolResponses()69     void refreshProtocolResponses() {
70         if (!mIsNetworkAvailable) {
71             return;
72         }
73         applyOffloadIntents(mOffloadIntentStore.getOffloadIntentsForInterface(mNetworkInterface));
74     }
75 
refreshPassthroughList()76     void refreshPassthroughList() {
77         if (!mIsNetworkAvailable) {
78             return;
79         }
80         applyPassthroughIntents(
81                 mOffloadIntentStore.getPassthroughIntentsForInterface(mNetworkInterface));
82     }
83 
retrieveAndClearMetrics()84     void retrieveAndClearMetrics() {
85         if (!mIsNetworkAvailable) {
86             return;
87         }
88         if (!mOffloadWriter.isVendorServiceConnected()) {
89             Log.e(TAG, "Vendor service disconnected, cannot apply mDNS offload state");
90             return;
91         }
92         mOffloadWriter.retrieveAndClearMetrics(mCurrentOffloadKeys);
93     }
94 
clearProtocolResponses()95     private void clearProtocolResponses() {
96         applyOffloadIntents(Collections.emptySet());
97     }
98 
clearPassthroughList()99     private void clearPassthroughList() {
100         applyPassthroughIntents(Collections.emptyList());
101     }
102 
applyOffloadIntents(Collection<OffloadIntentStore.OffloadIntent> offloadIntents)103     private void applyOffloadIntents(Collection<OffloadIntentStore.OffloadIntent> offloadIntents) {
104         if (!mOffloadWriter.isVendorServiceConnected()) {
105             Log.e(TAG, "Vendor service disconnected, cannot apply mDNS offload state");
106             return;
107         }
108         Collection<Integer> deleted = mOffloadWriter.deleteOffloadData(mCurrentOffloadKeys);
109         mCurrentOffloadKeys.removeAll(deleted);
110         Collection<Integer> offloaded = mOffloadWriter.writeOffloadData(
111                 mNetworkInterface, offloadIntents);
112         mCurrentOffloadKeys.addAll(offloaded);
113     }
114 
applyPassthroughIntents( List<OffloadIntentStore.PassthroughIntent> passthroughIntents)115     private void applyPassthroughIntents(
116             List<OffloadIntentStore.PassthroughIntent> passthroughIntents) {
117         if (!mOffloadWriter.isVendorServiceConnected()){
118             Log.e(TAG, "Vendor service disconnected, cannot apply mDNS passthrough state");
119             return;
120         }
121         Collection<String> deleted = mOffloadWriter.deletePassthroughData(
122                 mNetworkInterface, mCurrentPassthroughQNames);
123         mCurrentPassthroughQNames.removeAll(deleted);
124         Collection<String> added = mOffloadWriter.writePassthroughData(
125                 mNetworkInterface, passthroughIntents);
126         mCurrentPassthroughQNames.addAll(added);
127     }
128 
129     @WorkerThread
dump(PrintWriter writer)130     void dump(PrintWriter writer) {
131         writer.println("InterfaceOffloadManager[%s]:".formatted(mNetworkInterface));
132         writer.println("mIsNetworkAvailable=%b".formatted(mIsNetworkAvailable));
133         writer.println("current offload keys:");
134         mCurrentOffloadKeys.forEach(key -> writer.println("* %d".formatted(key)));
135         writer.println("current passthrough qnames:");
136         mCurrentPassthroughQNames.forEach(qname -> writer.println("* %s".formatted(qname)));
137         writer.println();
138     }
139 
140 }
141