1 package com.android.settings.wifi; 2 3 import android.app.Activity; 4 import android.app.Fragment; 5 import android.content.ComponentName; 6 import android.content.ContentResolver; 7 import android.content.Context; 8 import android.content.Intent; 9 import android.database.ContentObserver; 10 import android.net.NetworkScoreManager; 11 12 import android.net.NetworkScorerAppData; 13 import android.net.Uri; 14 import android.os.Handler; 15 import android.os.Looper; 16 import android.provider.Settings; 17 import android.support.annotation.VisibleForTesting; 18 import android.support.v14.preference.SwitchPreference; 19 import android.support.v7.preference.Preference; 20 import android.support.v7.preference.PreferenceScreen; 21 import android.text.TextUtils; 22 23 import com.android.settings.network.NetworkScoreManagerWrapper; 24 import com.android.settings.core.PreferenceController; 25 import com.android.settings.core.lifecycle.Lifecycle; 26 import com.android.settings.core.lifecycle.LifecycleObserver; 27 import com.android.settings.core.lifecycle.events.OnPause; 28 import com.android.settings.core.lifecycle.events.OnResume; 29 30 /** 31 * {@link PreferenceController} that controls whether a user wants to enable the "use open networks 32 * automatically" feature provider by the current network recommendation provider. 33 */ 34 public class UseOpenWifiPreferenceController extends PreferenceController 35 implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause { 36 private static final String KEY_USE_OPEN_WIFI_AUTOMATICALLY = "use_open_wifi_automatically"; 37 @VisibleForTesting static final int REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY = 400; 38 39 private final ContentResolver mContentResolver; 40 private final Fragment mFragment; 41 private final NetworkScoreManagerWrapper mNetworkScoreManagerWrapper; 42 private final SettingObserver mSettingObserver; 43 44 private Preference mPreference; 45 private ComponentName mEnableUseWifiComponentName; 46 47 public UseOpenWifiPreferenceController(Context context, Fragment fragment, 48 NetworkScoreManagerWrapper networkScoreManagerWrapper, Lifecycle lifecycle) { 49 super(context); 50 mContentResolver = context.getContentResolver(); 51 mFragment = fragment; 52 mNetworkScoreManagerWrapper = networkScoreManagerWrapper; 53 mSettingObserver = new SettingObserver(); 54 updateEnableUseWifiComponentName(); 55 lifecycle.addObserver(this); 56 } 57 58 private void updateEnableUseWifiComponentName() { 59 NetworkScorerAppData appData = mNetworkScoreManagerWrapper.getActiveScorer(); 60 mEnableUseWifiComponentName = 61 appData == null ? null : appData.getEnableUseOpenWifiActivity(); 62 } 63 64 @Override 65 public void displayPreference(PreferenceScreen screen) { 66 super.displayPreference(screen); 67 mPreference = screen.findPreference(KEY_USE_OPEN_WIFI_AUTOMATICALLY); 68 } 69 70 @Override 71 public void onResume() { 72 mSettingObserver.register(mContentResolver); 73 } 74 75 @Override 76 public void onPause() { 77 mSettingObserver.unregister(mContentResolver); 78 } 79 80 @Override 81 public boolean isAvailable() { 82 return mEnableUseWifiComponentName != null; 83 } 84 85 @Override 86 public String getPreferenceKey() { 87 return KEY_USE_OPEN_WIFI_AUTOMATICALLY; 88 } 89 90 @Override 91 public void updateState(Preference preference) { 92 if (!(preference instanceof SwitchPreference)) { 93 return; 94 } 95 final SwitchPreference useOpenWifiPreference = (SwitchPreference) preference; 96 useOpenWifiPreference.setVisible(isAvailable()); 97 useOpenWifiPreference.setChecked(isSettingEnabled()); 98 } 99 100 @Override 101 public boolean onPreferenceChange(Preference preference, Object newValue) { 102 if (!TextUtils.equals(preference.getKey(), KEY_USE_OPEN_WIFI_AUTOMATICALLY) 103 || !isAvailable()) { 104 return false; 105 } 106 107 if (isSettingEnabled()) { 108 Settings.Global.putString(mContentResolver, 109 Settings.Global.USE_OPEN_WIFI_PACKAGE, ""); 110 return true; 111 } 112 113 Intent intent = new Intent(NetworkScoreManager.ACTION_CUSTOM_ENABLE); 114 intent.setComponent(mEnableUseWifiComponentName); 115 mFragment.startActivityForResult(intent, REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY); 116 return false; // Updating state is done in onActivityResult. 117 } 118 119 private boolean isSettingEnabled() { 120 String enabledUseOpenWifiPackage = Settings.Global.getString(mContentResolver, 121 Settings.Global.USE_OPEN_WIFI_PACKAGE); 122 String currentUseOpenWifiPackage = mEnableUseWifiComponentName == null 123 ? null : mEnableUseWifiComponentName.getPackageName(); 124 return TextUtils.equals(enabledUseOpenWifiPackage, currentUseOpenWifiPackage); 125 } 126 127 public boolean onActivityResult(int requestCode, int resultCode) { 128 if (requestCode != REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY) { 129 return false; 130 } 131 132 if (resultCode == Activity.RESULT_OK) { 133 Settings.Global.putString(mContentResolver, Settings.Global.USE_OPEN_WIFI_PACKAGE, 134 mEnableUseWifiComponentName.getPackageName()); 135 } 136 return true; 137 } 138 139 class SettingObserver extends ContentObserver { 140 private final Uri NETWORK_RECOMMENDATIONS_ENABLED_URI = 141 Settings.Global.getUriFor(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED); 142 143 public SettingObserver() { 144 super(new Handler(Looper.getMainLooper())); 145 } 146 147 public void register(ContentResolver cr) { 148 cr.registerContentObserver(NETWORK_RECOMMENDATIONS_ENABLED_URI, false, this); 149 onChange(true /* selfChange */, NETWORK_RECOMMENDATIONS_ENABLED_URI); 150 } 151 152 public void unregister(ContentResolver cr) { 153 cr.unregisterContentObserver(this); 154 } 155 156 @Override 157 public void onChange(boolean selfChange, Uri uri) { 158 super.onChange(selfChange, uri); 159 if (NETWORK_RECOMMENDATIONS_ENABLED_URI.equals(uri)) { 160 updateEnableUseWifiComponentName(); 161 updateState(mPreference); 162 } 163 } 164 } 165 } 166