• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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;
18 
19 import android.content.Context;
20 import android.net.EthernetManager;
21 import android.net.TetheringManager;
22 import android.os.Handler;
23 import android.os.Looper;
24 
25 import androidx.lifecycle.Lifecycle;
26 import androidx.lifecycle.OnLifecycleEvent;
27 
28 import com.android.internal.annotations.VisibleForTesting;
29 
30 import java.util.HashSet;
31 
32 /**
33  * This controller helps to manage the switch state and visibility of ethernet tether switch
34  * preference.
35  */
36 public final class EthernetTetherPreferenceController extends TetherBasePreferenceController {
37 
38     private final HashSet<String> mAvailableInterfaces = new HashSet<>();
39     private final EthernetManager mEthernetManager;
40 
41     @VisibleForTesting
42     EthernetManager.InterfaceStateListener mEthernetListener;
43 
EthernetTetherPreferenceController(Context context, String preferenceKey)44     public EthernetTetherPreferenceController(Context context, String preferenceKey) {
45         super(context, preferenceKey);
46         mEthernetManager = context.getSystemService(EthernetManager.class);
47     }
48 
49     @OnLifecycleEvent(Lifecycle.Event.ON_START)
onStart()50     public void onStart() {
51         mEthernetListener = (iface, state, role, configuration) -> {
52             if (state == EthernetManager.STATE_LINK_UP) {
53                 mAvailableInterfaces.add(iface);
54             } else {
55                 mAvailableInterfaces.remove(iface);
56             }
57             updateState(mPreference);
58         };
59         final Handler handler = new Handler(Looper.getMainLooper());
60         // Executor will execute to post the updateState event to a new handler which is created
61         // from the main looper when the {@link EthernetManager.Listener.onAvailabilityChanged}
62         // is triggerd.
63         if (mEthernetManager != null) {
64             mEthernetManager.addInterfaceStateListener(r -> handler.post(r), mEthernetListener);
65         }
66     }
67 
68     @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
onStop()69     public void onStop() {
70         if (mEthernetManager != null) {
71             mEthernetManager.removeInterfaceStateListener(mEthernetListener);
72         }
73     }
74 
75     @Override
shouldEnable()76     public boolean shouldEnable() {
77         ensureRunningOnMainLoopThread();
78         String[] available = mTm.getTetherableIfaces();
79         for (String s : available) {
80             if (mAvailableInterfaces.contains(s)) {
81                 return true;
82             }
83         }
84         return false;
85     }
86 
87     @Override
shouldShow()88     public boolean shouldShow() {
89         return mEthernetManager != null;
90     }
91 
92     @Override
getTetherType()93     public int getTetherType() {
94         return TetheringManager.TETHERING_ETHERNET;
95     }
96 
ensureRunningOnMainLoopThread()97     private void ensureRunningOnMainLoopThread() {
98         if (Looper.getMainLooper().getThread() != Thread.currentThread()) {
99             throw new IllegalStateException(
100                     "Not running on main loop thread: "
101                             + Thread.currentThread().getName());
102         }
103     }
104 }
105