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.ConnectivityManager;
21 
22 import androidx.lifecycle.Lifecycle;
23 import androidx.lifecycle.LifecycleObserver;
24 import androidx.lifecycle.OnLifecycleEvent;
25 import androidx.preference.Preference;
26 import androidx.preference.PreferenceScreen;
27 
28 import com.android.settings.core.TogglePreferenceController;
29 import com.android.settings.datausage.DataSaverBackend;
30 
31 public abstract class TetherBasePreferenceController extends TogglePreferenceController
32         implements LifecycleObserver,  DataSaverBackend.Listener,
33         TetherEnabler.OnTetherStateUpdateListener {
34 
35     private static final String TAG = "TetherBasePreferenceController";
36     final ConnectivityManager mCm;
37     private final DataSaverBackend mDataSaverBackend;
38 
39     private TetherEnabler mTetherEnabler;
40     Preference mPreference;
41     private boolean mDataSaverEnabled;
42     int mTetheringState;
43 
TetherBasePreferenceController(Context context, String preferenceKey)44     TetherBasePreferenceController(Context context, String preferenceKey) {
45         super(context, preferenceKey);
46         mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
47         mDataSaverBackend = new DataSaverBackend(context);
48         mDataSaverEnabled = mDataSaverBackend.isDataSaverEnabled();
49     }
50 
51     /**
52      * Set TetherEnabler for the controller. Call this method to initialize the controller.
53      * @param tetherEnabler The tetherEnabler to set for the controller.
54      */
setTetherEnabler(TetherEnabler tetherEnabler)55     public void setTetherEnabler(TetherEnabler tetherEnabler) {
56         mTetherEnabler = tetherEnabler;
57     }
58 
59     @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
onResume()60     public void onResume() {
61         // Must call setEnabler() before
62         if (mTetherEnabler != null) {
63             mTetherEnabler.addListener(this);
64         }
65         mDataSaverBackend.addListener(this);
66     }
67 
68     @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
onPause()69     public void onPause() {
70         if (mTetherEnabler != null) {
71             mTetherEnabler.removeListener(this);
72         }
73         mDataSaverBackend.remListener(this);
74     }
75 
76     @Override
isChecked()77     public boolean isChecked() {
78         return TetherEnabler.isTethering(mTetheringState, getTetherType());
79     }
80 
81     @Override
setChecked(boolean isChecked)82     public boolean setChecked(boolean isChecked) {
83         if (mTetherEnabler == null) {
84             return false;
85         }
86         if (isChecked) {
87             mTetherEnabler.startTethering(getTetherType());
88         } else {
89             mTetherEnabler.stopTethering(getTetherType());
90         }
91         return true;
92     }
93 
94     @Override
displayPreference(PreferenceScreen screen)95     public void displayPreference(PreferenceScreen screen) {
96         super.displayPreference(screen);
97         mPreference = screen.findPreference(mPreferenceKey);
98     }
99 
100     @Override
updateState(Preference preference)101     public void updateState(Preference preference) {
102         super.updateState(preference);
103         if (isAvailable()) {
104             preference.setEnabled(getAvailabilityStatus() != DISABLED_DEPENDENT_SETTING);
105         }
106     }
107 
108     @Override
getAvailabilityStatus()109     public int getAvailabilityStatus() {
110         if (!shouldShow()) {
111             return CONDITIONALLY_UNAVAILABLE;
112         }
113 
114         if (mDataSaverEnabled || !shouldEnable()) {
115             return DISABLED_DEPENDENT_SETTING;
116         }
117         return AVAILABLE;
118     }
119 
120     @Override
onTetherStateUpdated(@etherEnabler.TetheringState int state)121     public void onTetherStateUpdated(@TetherEnabler.TetheringState int state) {
122         mTetheringState = state;
123         updateState(mPreference);
124     }
125 
126     @Override
onDataSaverChanged(boolean isDataSaving)127     public void onDataSaverChanged(boolean isDataSaving) {
128         mDataSaverEnabled = isDataSaving;
129     }
130 
131     @Override
onWhitelistStatusChanged(int uid, boolean isWhitelisted)132     public void onWhitelistStatusChanged(int uid, boolean isWhitelisted) {
133     }
134 
135     @Override
onBlacklistStatusChanged(int uid, boolean isBlacklisted)136     public void onBlacklistStatusChanged(int uid, boolean isBlacklisted) {
137     }
138 
139     /**
140      * Used to enable or disable the preference.
141      * @return true if the preference should be enabled; false otherwise.
142      */
shouldEnable()143     public abstract boolean shouldEnable();
144 
145     /**
146      * Used to determine visibility of the preference.
147      * @return true if the preference should be visible; false otherwise.
148      */
shouldShow()149     public abstract boolean shouldShow();
150 
151     /**
152      * Get the type of tether interface that is controlled by the preference.
153      * @return the tether interface, like {@link ConnectivityManager#TETHERING_WIFI}
154      */
getTetherType()155     public abstract int getTetherType();
156 }
157