1 /*
2  * Copyright (C) 2016 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.tv.settings.connectivity;
18 
19 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_CLASSIC;
20 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_TWO_PANEL;
21 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_VENDOR;
22 import static com.android.tv.settings.overlay.FlavorUtils.FLAVOR_X;
23 import static com.android.tv.settings.util.InstrumentationUtils.logEntrySelected;
24 import static com.android.tv.settings.util.InstrumentationUtils.logToggleInteracted;
25 
26 import android.app.tvsettings.TvSettingsEnums;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.pm.PackageManager;
30 import android.content.pm.ResolveInfo;
31 import android.net.ConnectivityManager;
32 import android.net.NetworkInfo;
33 import android.net.wifi.WifiManager;
34 import android.os.Build;
35 import android.os.Bundle;
36 import android.os.Handler;
37 import android.os.SystemClock;
38 import android.os.SystemProperties;
39 import android.os.UserManager;
40 import android.provider.Settings;
41 import android.util.ArrayMap;
42 import android.view.View;
43 
44 import androidx.annotation.Keep;
45 import androidx.preference.Preference;
46 import androidx.preference.PreferenceCategory;
47 import androidx.preference.PreferenceManager;
48 import androidx.preference.TwoStatePreference;
49 
50 import com.android.settingslib.RestrictedPreference;
51 import com.android.tv.settings.MainFragment;
52 import com.android.tv.settings.R;
53 import com.android.tv.settings.RestrictedPreferenceAdapter;
54 import com.android.tv.settings.SettingsPreferenceFragment;
55 import com.android.tv.settings.basic.BasicModeFeatureProvider;
56 import com.android.tv.settings.library.network.AccessPoint;
57 import com.android.tv.settings.overlay.FlavorUtils;
58 import com.android.tv.settings.util.SliceUtils;
59 import com.android.tv.settings.widget.AccessPointPreference;
60 import com.android.tv.settings.widget.CustomContentDescriptionSwitchPreference;
61 import com.android.tv.settings.widget.TvAccessPointPreference;
62 import com.android.tv.twopanelsettings.slices.SlicePreference;
63 import com.android.wifitrackerlib.WifiEntry;
64 
65 import java.util.ArrayList;
66 import java.util.Collection;
67 import java.util.Collections;
68 import java.util.HashSet;
69 import java.util.List;
70 import java.util.Map;
71 import java.util.Set;
72 
73 /**
74  * Fragment for controlling network connectivity
75  */
76 @Keep
77 public class NetworkFragment extends SettingsPreferenceFragment implements
78         ConnectivityListener.Listener, ConnectivityListener.WifiNetworkListener,
79         AccessPoint.AccessPointListener {
80 
81     private static final String KEY_WIFI_ENABLE = "wifi_enable";
82     private static final String KEY_WIFI_LIST = "wifi_list";
83     private static final String KEY_WIFI_COLLAPSE = "wifi_collapse";
84     private static final String KEY_WIFI_OTHER = "wifi_other";
85     private static final String KEY_WIFI_ADD = "wifi_add";
86     private static final String KEY_WIFI_ADD_EASYCONNECT = "wifi_add_easyconnect";
87     private static final String KEY_WIFI_ALWAYS_SCAN = "wifi_always_scan";
88     private static final String KEY_ETHERNET = "ethernet";
89     private static final String KEY_ETHERNET_STATUS = "ethernet_status";
90     private static final String KEY_ETHERNET_PROXY = "ethernet_proxy";
91     private static final String KEY_ETHERNET_DHCP = "ethernet_dhcp";
92     private static final String KEY_NETWORK_DIAGNOSTICS = "network_diagnostics";
93 
94     private static final int INITIAL_UPDATE_DELAY = 500;
95 
96     private static final String NETWORK_DIAGNOSTICS_ACTION =
97             "com.android.tv.settings.network.NETWORK_DIAGNOSTICS";
98 
99     private ConnectivityListener mConnectivityListener;
100     private WifiManager mWifiManager;
101     private ConnectivityManager mConnectivityManager;
102     private TvAccessPointPreference.UserBadgeCache mUserBadgeCache;
103 
104     private TwoStatePreference mEnableWifiPref;
105     private CollapsibleCategory mWifiNetworksCategory;
106     private Preference mCollapsePref;
107     private RestrictedPreference mAddPref;
108     private RestrictedPreference mAddEasyConnectPref;
109     private TwoStatePreference mAlwaysScan;
110     private PreferenceCategory mEthernetCategory;
111     private Preference mEthernetStatusPref;
112     private Preference mEthernetProxyPref;
113     private Preference mEthernetDhcpPref;
114     private Map<WifiEntry, RestrictedPreferenceAdapter<TvAccessPointPreference>> mPrefMap =
115             Collections.emptyMap();
116 
117     private final Handler mHandler = new Handler();
118     private long mNoWifiUpdateBeforeMillis;
119     private Runnable mInitialUpdateWifiListRunnable = new Runnable() {
120         @Override
121         public void run() {
122             mNoWifiUpdateBeforeMillis = 0;
123             updateWifiList();
124         }
125     };
126     private boolean mIsWifiHardwarePresent;
127 
newInstance()128     public static NetworkFragment newInstance() {
129         return new NetworkFragment();
130     }
131 
132     private final List<AccessPoint> mCurrentAccessPoints = new ArrayList<>();
133 
134     @Override
onCreate(Bundle savedInstanceState)135     public void onCreate(Bundle savedInstanceState) {
136         mIsWifiHardwarePresent = getContext().getPackageManager()
137                 .hasSystemFeature(PackageManager.FEATURE_WIFI);
138         mConnectivityListener = new ConnectivityListener(
139                 getContext(), this, getSettingsLifecycle());
140         mWifiManager = getContext().getSystemService(WifiManager.class);
141         mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
142         mUserBadgeCache =
143                 new TvAccessPointPreference.UserBadgeCache(getContext().getPackageManager());
144         super.onCreate(savedInstanceState);
145     }
146 
147     @Override
onStart()148     public void onStart() {
149         super.onStart();
150         mConnectivityListener.setWifiListener(this);
151         mNoWifiUpdateBeforeMillis = SystemClock.elapsedRealtime() + INITIAL_UPDATE_DELAY;
152         updateWifiList();
153     }
154 
155     @Override
onResume()156     public void onResume() {
157         super.onResume();
158         // There doesn't seem to be an API to listen to everything this could cover, so
159         // tickle it here and hope for the best.
160         updateConnectivity();
161     }
162 
163 
164     @Override
onStop()165     public void onStop() {
166         mConnectivityListener.setListener(null);
167         clearCurrentAccessPoints();
168         super.onStop();
169     }
170 
getPreferenceScreenResId()171     private int getPreferenceScreenResId() {
172         switch (FlavorUtils.getFlavor(getContext())) {
173             case FLAVOR_CLASSIC:
174             case FLAVOR_TWO_PANEL:
175                 return R.xml.network;
176             case FLAVOR_X:
177             case FLAVOR_VENDOR:
178                 return R.xml.network_x;
179             default:
180                 return R.xml.network;
181         }
182     }
183 
184     @Override
onCreatePreferences(Bundle savedInstanceState, String rootKey)185     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
186         getPreferenceManager().setPreferenceComparisonCallback(
187                 new PreferenceManager.SimplePreferenceComparisonCallback());
188         setPreferencesFromResource(getPreferenceScreenResId(), null);
189 
190         mEnableWifiPref = (TwoStatePreference) findPreference(KEY_WIFI_ENABLE);
191         mWifiNetworksCategory = (CollapsibleCategory) findPreference(KEY_WIFI_LIST);
192         mCollapsePref = findPreference(KEY_WIFI_COLLAPSE);
193         mAddPref = (RestrictedPreference) findPreference(KEY_WIFI_ADD);
194         mAddEasyConnectPref = (RestrictedPreference) findPreference(KEY_WIFI_ADD_EASYCONNECT);
195         mAlwaysScan = (TwoStatePreference) findPreference(KEY_WIFI_ALWAYS_SCAN);
196 
197         mEthernetCategory = (PreferenceCategory) findPreference(KEY_ETHERNET);
198         mEthernetStatusPref = findPreference(KEY_ETHERNET_STATUS);
199         mEthernetProxyPref = findPreference(KEY_ETHERNET_PROXY);
200         mEthernetDhcpPref = findPreference(KEY_ETHERNET_DHCP);
201 
202         if (!mIsWifiHardwarePresent) {
203             mEnableWifiPref.setVisible(false);
204         }
205 
206         Preference networkDiagnosticsPref = findPreference(KEY_NETWORK_DIAGNOSTICS);
207         Intent networkDiagnosticsIntent = makeNetworkDiagnosticsIntent();
208         if (networkDiagnosticsIntent != null) {
209             networkDiagnosticsPref.setVisible(true);
210             networkDiagnosticsPref.setIntent(networkDiagnosticsIntent);
211         } else {
212             networkDiagnosticsPref.setVisible(false);
213         }
214 
215         final UserManager userManager = UserManager.get(getContext());
216 
217         mAddPref.checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_WIFI);
218         mAddEasyConnectPref.checkRestrictionAndSetDisabled(UserManager.DISALLOW_CONFIG_WIFI);
219 
220         if (!mAddPref.isDisabledByAdmin()) {
221             mAddPref.checkRestrictionAndSetDisabled(UserManager.DISALLOW_ADD_WIFI_CONFIG);
222             mAddEasyConnectPref.checkRestrictionAndSetDisabled(
223                     UserManager.DISALLOW_ADD_WIFI_CONFIG);
224         }
225 
226         if (userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI)
227                 || userManager.hasUserRestriction(UserManager.DISALLOW_ADD_WIFI_CONFIG)) {
228             mAddPref.setFragment(null);
229             mAddEasyConnectPref.setFragment(null);
230 
231             if (!mAddPref.isDisabledByAdmin()) {
232                 mAddPref.setEnabled(false);
233             }
234             if (!mAddEasyConnectPref.isDisabledByAdmin()) {
235                 mAddEasyConnectPref.setEnabled(false);
236             }
237         }
238     }
239 
240     @Override
onPreferenceTreeClick(Preference preference)241     public boolean onPreferenceTreeClick(Preference preference) {
242         if (preference.getKey() == null) {
243             return super.onPreferenceTreeClick(preference);
244         }
245         switch (preference.getKey()) {
246             case KEY_WIFI_ENABLE:
247                 BasicModeFeatureProvider provider = FlavorUtils.getFeatureFactory(
248                         getContext()).getBasicModeFeatureProvider();
249                 if (mEnableWifiPref.isChecked() &&
250                         Settings.Global.getInt(
251                                 getContext().getContentResolver(), Settings.Global.ADB_ENABLED, 0)
252                                 != 1 && SystemProperties.getInt(
253                         "ro.product.first_api_level", Build.VERSION.SDK_INT)
254                         >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && provider.isBasicMode(
255                         getContext())
256                         && !provider.isStoreDemoMode(getContext())) {
257                     // WiFi turned ON + not developer + launched on U+ + basic mode.
258                     // Prevent WiFi connection by launching dialog instead.
259                     provider.startBasicModeInternetBlock(getActivity());
260                 } else {
261                     mConnectivityListener.setWifiEnabled(mEnableWifiPref.isChecked());
262                 }
263                 logToggleInteracted(
264                         TvSettingsEnums.NETWORK_WIFI_ON_OFF, mEnableWifiPref.isChecked());
265                 return true;
266             case KEY_WIFI_COLLAPSE:
267                 final boolean collapse = !mWifiNetworksCategory.isCollapsed();
268                 View collapsePrefView = getListView().getChildAt(mCollapsePref.getOrder());
269                 String wifiCollapseTitle = getContext().getString(collapse
270                         ? R.string.wifi_setting_see_all : R.string.wifi_setting_see_fewer);
271                 mCollapsePref.setTitle(wifiCollapseTitle);
272                 if (collapsePrefView != null) {
273                     collapsePrefView.setAccessibilityPaneTitle(wifiCollapseTitle);
274                 }
275                 mWifiNetworksCategory.setCollapsed(collapse);
276                 logEntrySelected(
277                         collapse
278                                 ? TvSettingsEnums.NETWORK_SEE_FEWER
279                                 : TvSettingsEnums.NETWORK_SEE_ALL);
280                 return true;
281             case KEY_WIFI_ALWAYS_SCAN:
282                 Settings.Global.putInt(getActivity().getContentResolver(),
283                         Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
284                         mAlwaysScan.isChecked() ? 1 : 0);
285                 logToggleInteracted(
286                         TvSettingsEnums.NETWORK_ALWAYS_SCANNING_NETWORKS, mAlwaysScan.isChecked());
287                 return true;
288             case KEY_ETHERNET_STATUS:
289                 return true;
290             case KEY_WIFI_ADD:
291                 logEntrySelected(TvSettingsEnums.NETWORK_ADD_NEW_NETWORK);
292                 break;
293             case KEY_WIFI_ADD_EASYCONNECT:
294                 startActivity(AddWifiNetworkActivity.createEasyConnectIntent(getContext()));
295                 break;
296         }
297         return super.onPreferenceTreeClick(preference);
298     }
299 
updateConnectivity()300     private void updateConnectivity() {
301         if (!isAdded()) {
302             return;
303         }
304 
305         final boolean wifiEnabled = mIsWifiHardwarePresent
306                 && mConnectivityListener.isWifiEnabledOrEnabling();
307         final boolean ethernetConnected = mConnectivityListener.isEthernetConnected();
308         mEnableWifiPref.setChecked(wifiEnabled);
309 
310         mWifiNetworksCategory.setVisible(wifiEnabled && !ethernetConnected);
311         mCollapsePref.setVisible(wifiEnabled && mWifiNetworksCategory.shouldShowCollapsePref());
312         mAddPref.setVisible(wifiEnabled && !ethernetConnected);
313         if (mAddEasyConnectPref != null) {
314             mAddEasyConnectPref.setVisible(isEasyConnectEnabled() && !ethernetConnected);
315         }
316 
317         if (!wifiEnabled) {
318             updateWifiList();
319         }
320 
321         int scanAlwaysAvailable = 0;
322         try {
323             scanAlwaysAvailable = Settings.Global.getInt(getContext().getContentResolver(),
324                     Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE);
325         } catch (Settings.SettingNotFoundException e) {
326             // Ignore
327         }
328         mAlwaysScan.setChecked(scanAlwaysAvailable == 1);
329         if (mAlwaysScan instanceof CustomContentDescriptionSwitchPreference) {
330             ((CustomContentDescriptionSwitchPreference) mAlwaysScan).setContentDescription(
331                     getResources()
332                             .getString(
333                                     R.string.wifi_setting_always_scan_content_description));
334         }
335 
336         final boolean ethernetAvailable = mConnectivityListener.isEthernetAvailable();
337         mEthernetCategory.setVisible(ethernetAvailable);
338         mEthernetStatusPref.setVisible(ethernetAvailable);
339         mEthernetProxyPref.setVisible(ethernetAvailable);
340         if (ethernetAvailable) {
341             mEthernetProxyPref.setIntent(EditProxySettingsActivity.createEthernetIntent(
342                     getContext(),
343                     mConnectivityListener.getEthernetInterfaceName(),
344                     mConnectivityListener.getEthernetIpConfiguration()));
345         }
346         mEthernetProxyPref.setOnPreferenceClickListener(
347                 preference -> {
348                     logEntrySelected(TvSettingsEnums.NETWORK_ETHERNET_PROXY_SETTINGS);
349                     return false;
350                 });
351 
352         mEthernetDhcpPref.setVisible(ethernetAvailable);
353         if (ethernetAvailable) {
354             mEthernetDhcpPref.setIntent(EditIpSettingsActivity.createEthernetIntent(getContext(),
355                     mConnectivityListener.getEthernetInterfaceName(),
356                     mConnectivityListener.getEthernetIpConfiguration()));
357         }
358         mEthernetDhcpPref.setOnPreferenceClickListener(
359                 preference -> {
360                     logEntrySelected(TvSettingsEnums.NETWORK_ETHERNET_IP_SETTINGS);
361                     return false;
362                 });
363 
364         if (ethernetAvailable) {
365             mEthernetStatusPref.setTitle(ethernetConnected
366                     ? R.string.connected : R.string.not_connected);
367             mEthernetStatusPref.setSummary(mConnectivityListener.getEthernetIpAddress());
368         }
369 
370         mEnableWifiPref.setSummary(ethernetConnected ?
371                 getString(R.string.unplug_ethernet_to_use_wifi) : null);
372     }
373 
updateWifiList()374     private void updateWifiList() {
375         if (!isAdded()) {
376             return;
377         }
378 
379         if (!mIsWifiHardwarePresent || !mConnectivityListener.isWifiEnabledOrEnabling()
380             || mConnectivityListener.isEthernetConnected()) {
381             mWifiNetworksCategory.removeAll();
382             mNoWifiUpdateBeforeMillis = 0;
383             return;
384         }
385 
386         final long now = SystemClock.elapsedRealtime();
387         if (mNoWifiUpdateBeforeMillis > now) {
388             mHandler.removeCallbacks(mInitialUpdateWifiListRunnable);
389             mHandler.postDelayed(mInitialUpdateWifiListRunnable,
390                     mNoWifiUpdateBeforeMillis - now);
391             return;
392         }
393 
394         final int existingCount = mWifiNetworksCategory.getRealPreferenceCount();
395         final Set<Preference> toRemove = new HashSet<>(existingCount);
396         for (int i = 0; i < existingCount; i++) {
397             toRemove.add(mWifiNetworksCategory.getPreference(i));
398         }
399 
400         final Context themedContext = getPreferenceManager().getContext();
401         final Collection<AccessPoint> newAccessPoints =
402                 mConnectivityListener.getAvailableNetworks();
403         int index = 0;
404 
405         final Map<WifiEntry, RestrictedPreferenceAdapter<TvAccessPointPreference>> newPrefMap =
406                 new ArrayMap<>();
407         for (final AccessPoint accessPoint : newAccessPoints) {
408             accessPoint.setListener(this);
409             RestrictedPreferenceAdapter<TvAccessPointPreference> restrictedPref =
410                     mPrefMap.get(accessPoint.getWifiEntry());
411             Preference pref;
412             if (restrictedPref == null) {
413                 pref = new TvAccessPointPreference(accessPoint, themedContext, mUserBadgeCache,
414                         false);
415                 List<String> userRestrictions = new ArrayList<>();
416                 userRestrictions.add(UserManager.DISALLOW_CONFIG_WIFI);
417                 userRestrictions.add(UserManager.DISALLOW_ADD_WIFI_CONFIG);
418                 restrictedPref = new RestrictedPreferenceAdapter(themedContext, pref,
419                         userRestrictions);
420                 restrictedPref.setApSaved(accessPoint.isSaved());
421             } else {
422                 restrictedPref.setApSaved(accessPoint.isSaved());
423                 toRemove.remove(restrictedPref.getPreference());
424                 pref = restrictedPref.getOriginalPreference();
425             }
426             newPrefMap.put(accessPoint.getWifiEntry(), restrictedPref);
427 
428             if (isCaptivePortal(accessPoint)) {
429                 pref.setFragment(null);
430                 pref.setIntent(null);
431                 pref.setOnPreferenceClickListener(preference -> {
432                     accessPoint.getWifiEntry().signIn(null);
433                     return true;
434                 });
435             } else if (accessPoint.isActive()) {
436                 pref.setFragment(WifiDetailsFragment.class.getName());
437                 // No need to track entry selection as new page will be focused
438                 pref.setOnPreferenceClickListener(preference -> false);
439                 WifiDetailsFragment.prepareArgs(pref.getExtras(), accessPoint);
440                 pref.setIntent(null);
441             } else {
442                 pref.setFragment(null);
443                 pref.setIntent(WifiConnectionActivity.createIntent(getContext(), accessPoint));
444                 pref.setOnPreferenceClickListener(
445                         preference -> {
446                             logEntrySelected(TvSettingsEnums.NETWORK_NOT_CONNECTED_AP);
447                             return false;
448                         });
449             }
450             pref.setVisible(!restrictedPref.isRestricted(UserManager.DISALLOW_CONFIG_WIFI)
451                     || accessPoint.isSaved());
452             pref.setOrder(index++);
453             pref.setSummary(WifiUtils.getConnectionStatus(accessPoint.getWifiEntry()));
454             restrictedPref.updatePreference();
455 
456             Preference restrictedChild = restrictedPref.getPreference();
457             if (restrictedChild.getParent() != null &&
458                     restrictedChild.getParent() != mWifiNetworksCategory) {
459                 // Remove first if added to parent from old fragment.
460                 restrictedChild.getParent().removePreference(restrictedChild);
461             }
462             mWifiNetworksCategory.addPreference(restrictedChild);
463         }
464 
465         for (final Preference preference : toRemove) {
466             mWifiNetworksCategory.removePreference(preference);
467         }
468 
469         mCollapsePref.setVisible(mWifiNetworksCategory.shouldShowCollapsePref());
470         mPrefMap = newPrefMap;
471 
472         clearCurrentAccessPoints();
473         mCurrentAccessPoints.addAll(newAccessPoints);
474     }
475 
clearCurrentAccessPoints()476     private void clearCurrentAccessPoints() {
477         for (AccessPoint accessPoint : mCurrentAccessPoints) {
478             accessPoint.setListener(null);
479         }
480         mCurrentAccessPoints.clear();
481     }
482 
isCaptivePortal(AccessPoint accessPoint)483     private boolean isCaptivePortal(AccessPoint accessPoint) {
484         return accessPoint.getWifiEntry().canSignIn();
485     }
486 
makeNetworkDiagnosticsIntent()487     private Intent makeNetworkDiagnosticsIntent() {
488         Intent intent = new Intent();
489         intent.setAction(NETWORK_DIAGNOSTICS_ACTION);
490 
491         ResolveInfo resolveInfo = MainFragment.systemIntentIsHandled(getContext(), intent);
492         if (resolveInfo == null || resolveInfo.activityInfo == null) {
493             return null;
494         }
495 
496         intent.setPackage(resolveInfo.activityInfo.packageName);
497 
498         return intent;
499     }
500 
501     @Override
onConnectivityChange()502     public void onConnectivityChange() {
503         updateConnectivity();
504     }
505 
506     @Override
onWifiListChanged()507     public void onWifiListChanged() {
508         updateWifiList();
509     }
510 
511     @Override
onAccessPointChanged(AccessPoint accessPoint)512     public void onAccessPointChanged(AccessPoint accessPoint) {
513         RestrictedPreferenceAdapter<TvAccessPointPreference> restrictedPref =
514                 mPrefMap.get(accessPoint.getWifiEntry());
515         restrictedPref.updatePreference(AccessPointPreference::refresh);
516     }
517 
518     @Override
onLevelChanged(AccessPoint accessPoint)519     public void onLevelChanged(AccessPoint accessPoint) {
520         RestrictedPreferenceAdapter<TvAccessPointPreference> restrictedPref =
521                 mPrefMap.get(accessPoint.getWifiEntry());
522         restrictedPref.updatePreference(AccessPointPreference::onLevelChanged);
523     }
524 
525     @Override
getPageId()526     protected int getPageId() {
527         return TvSettingsEnums.NETWORK;
528     }
529 
isEasyConnectEnabled()530     private boolean isEasyConnectEnabled() {
531         final boolean wifiEnabled = mIsWifiHardwarePresent
532                 && mConnectivityListener.isWifiEnabledOrEnabling();
533 
534         if (!wifiEnabled || !mWifiManager.isEasyConnectSupported()) {
535             return false;
536         }
537 
538         return getContext().getResources().getBoolean(R.bool.config_easyconnect_enabled);
539     }
540 }
541