• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
20 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
21 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
22 import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
23 import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
24 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
25 
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.content.res.Resources;
29 import android.database.ContentObserver;
30 import android.net.ConnectivityManager;
31 import android.net.ConnectivityManager.NetworkCallback;
32 import android.net.LinkProperties;
33 import android.net.Network;
34 import android.net.Uri;
35 import android.os.Handler;
36 import android.os.Looper;
37 import android.os.UserHandle;
38 import android.os.UserManager;
39 import android.provider.Settings;
40 
41 import androidx.preference.Preference;
42 import androidx.preference.PreferenceScreen;
43 
44 import com.android.internal.util.ArrayUtils;
45 import com.android.settings.R;
46 import com.android.settings.core.BasePreferenceController;
47 import com.android.settings.core.PreferenceControllerMixin;
48 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
49 import com.android.settingslib.RestrictedLockUtilsInternal;
50 import com.android.settingslib.core.lifecycle.LifecycleObserver;
51 import com.android.settingslib.core.lifecycle.events.OnStart;
52 import com.android.settingslib.core.lifecycle.events.OnStop;
53 
54 import java.net.InetAddress;
55 import java.util.List;
56 
57 public class PrivateDnsPreferenceController extends BasePreferenceController
58         implements PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop {
59     private static final String KEY_PRIVATE_DNS_SETTINGS = "private_dns_settings";
60 
61     private static final Uri[] SETTINGS_URIS = new Uri[]{
62         Settings.Global.getUriFor(PRIVATE_DNS_MODE),
63         Settings.Global.getUriFor(PRIVATE_DNS_DEFAULT_MODE),
64         Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER),
65     };
66 
67     private final Handler mHandler;
68     private final ContentObserver mSettingsObserver;
69     private final ConnectivityManager mConnectivityManager;
70     private LinkProperties mLatestLinkProperties;
71     private Preference mPreference;
72 
PrivateDnsPreferenceController(Context context)73     public PrivateDnsPreferenceController(Context context) {
74         super(context, KEY_PRIVATE_DNS_SETTINGS);
75         mHandler = new Handler(Looper.getMainLooper());
76         mSettingsObserver = new PrivateDnsSettingsObserver(mHandler);
77         mConnectivityManager = context.getSystemService(ConnectivityManager.class);
78     }
79 
80     @Override
getPreferenceKey()81     public String getPreferenceKey() {
82         return KEY_PRIVATE_DNS_SETTINGS;
83     }
84 
85     @Override
getAvailabilityStatus()86     public int getAvailabilityStatus() {
87         return mContext.getResources().getBoolean(R.bool.config_show_private_dns_settings)
88                 ? AVAILABLE
89                 : UNSUPPORTED_ON_DEVICE;
90     }
91 
92     @Override
displayPreference(PreferenceScreen screen)93     public void displayPreference(PreferenceScreen screen) {
94         super.displayPreference(screen);
95 
96         mPreference = screen.findPreference(getPreferenceKey());
97     }
98 
99     @Override
onStart()100     public void onStart() {
101         for (Uri uri : SETTINGS_URIS) {
102             mContext.getContentResolver().registerContentObserver(uri, false, mSettingsObserver);
103         }
104         final Network defaultNetwork = mConnectivityManager.getActiveNetwork();
105         if (defaultNetwork != null) {
106             mLatestLinkProperties = mConnectivityManager.getLinkProperties(defaultNetwork);
107         }
108         mConnectivityManager.registerDefaultNetworkCallback(mNetworkCallback, mHandler);
109     }
110 
111     @Override
onStop()112     public void onStop() {
113         mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
114         mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
115     }
116 
117     @Override
getSummary()118     public CharSequence getSummary() {
119         final Resources res = mContext.getResources();
120         final ContentResolver cr = mContext.getContentResolver();
121         final String mode = PrivateDnsModeDialogPreference.getModeFromSettings(cr);
122         final LinkProperties lp = mLatestLinkProperties;
123         final List<InetAddress> dnses = (lp == null) ? null : lp.getValidatedPrivateDnsServers();
124         final boolean dnsesResolved = !ArrayUtils.isEmpty(dnses);
125         switch (mode) {
126             case PRIVATE_DNS_MODE_OFF:
127                 return res.getString(R.string.private_dns_mode_off);
128             case PRIVATE_DNS_MODE_OPPORTUNISTIC:
129                 // TODO (b/79122154) : create a string specifically for this, instead of
130                 // hijacking a string from notifications. This is necessary at this time
131                 // because string freeze is in the past and this string has the right
132                 // content at this moment.
133                 return dnsesResolved ? res.getString(R.string.switch_on_text)
134                         : res.getString(R.string.private_dns_mode_opportunistic);
135             case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
136                 return dnsesResolved
137                         ? PrivateDnsModeDialogPreference.getHostnameFromSettings(cr)
138                         : res.getString(R.string.private_dns_mode_provider_failure);
139         }
140         return "";
141     }
142 
143     @Override
updateState(Preference preference)144     public void updateState(Preference preference) {
145         super.updateState(preference);
146         preference.setEnabled(!isManagedByAdmin());
147     }
148 
isManagedByAdmin()149     private boolean isManagedByAdmin() {
150         EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
151                 mContext, UserManager.DISALLOW_CONFIG_PRIVATE_DNS, UserHandle.myUserId());
152         return enforcedAdmin != null;
153     }
154 
155     private class PrivateDnsSettingsObserver extends ContentObserver {
PrivateDnsSettingsObserver(Handler h)156         public PrivateDnsSettingsObserver(Handler h) {
157             super(h);
158         }
159 
160         @Override
onChange(boolean selfChange)161         public void onChange(boolean selfChange) {
162             if (mPreference != null) {
163                 updateState(mPreference);
164             }
165         }
166     }
167 
168     private final NetworkCallback mNetworkCallback = new NetworkCallback() {
169         @Override
170         public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
171             mLatestLinkProperties = lp;
172             if (mPreference != null) {
173                 updateState(mPreference);
174             }
175         }
176         @Override
177         public void onLost(Network network) {
178             mLatestLinkProperties = null;
179             if (mPreference != null) {
180                 updateState(mPreference);
181             }
182         }
183     };
184 }
185