WirelessSettings.java revision a2904f9d5091ef5055d97adf72d32e8c19551c8e
1/* 2 * Copyright (C) 2009 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 17package com.android.settings; 18 19 20import android.app.Activity; 21import android.app.AlertDialog; 22import android.app.Dialog; 23import android.app.admin.DevicePolicyManager; 24import android.content.Context; 25import android.content.DialogInterface; 26import android.content.Intent; 27import android.content.pm.PackageManager; 28import android.content.res.Resources; 29import android.net.ConnectivityManager; 30import android.net.NetworkInfo; 31import android.nfc.NfcAdapter; 32import android.os.Bundle; 33import android.os.SystemProperties; 34import android.os.UserHandle; 35import android.preference.CheckBoxPreference; 36import android.preference.Preference; 37import android.preference.PreferenceScreen; 38import android.provider.Settings; 39import android.telephony.TelephonyManager; 40import android.text.TextUtils; 41import android.util.Log; 42import com.android.internal.telephony.TelephonyIntents; 43import com.android.internal.telephony.TelephonyProperties; 44import com.android.settings.nfc.NfcEnabler; 45import com.android.settings.NsdEnabler; 46 47public class WirelessSettings extends RestrictedSettingsFragment { 48 private static final String TAG = "WirelessSettings"; 49 50 private static final String KEY_TOGGLE_AIRPLANE = "toggle_airplane"; 51 private static final String KEY_TOGGLE_NFC = "toggle_nfc"; 52 private static final String KEY_WIMAX_SETTINGS = "wimax_settings"; 53 private static final String KEY_ANDROID_BEAM_SETTINGS = "android_beam_settings"; 54 private static final String KEY_VPN_SETTINGS = "vpn_settings"; 55 private static final String KEY_TETHER_SETTINGS = "tether_settings"; 56 private static final String KEY_PROXY_SETTINGS = "proxy_settings"; 57 private static final String KEY_MOBILE_NETWORK_SETTINGS = "mobile_network_settings"; 58 private static final String KEY_MANAGE_MOBILE_PLAN = "manage_mobile_plan"; 59 private static final String KEY_TOGGLE_NSD = "toggle_nsd"; //network service discovery 60 private static final String KEY_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings"; 61 62 public static final String EXIT_ECM_RESULT = "exit_ecm_result"; 63 public static final int REQUEST_CODE_EXIT_ECM = 1; 64 65 private AirplaneModeEnabler mAirplaneModeEnabler; 66 private CheckBoxPreference mAirplaneModePreference; 67 private NfcEnabler mNfcEnabler; 68 private NfcAdapter mNfcAdapter; 69 private NsdEnabler mNsdEnabler; 70 71 private ConnectivityManager mCm; 72 private TelephonyManager mTm; 73 74 private static final int MANAGE_MOBILE_PLAN_DIALOG_ID = 1; 75 private static final String SAVED_MANAGE_MOBILE_PLAN_MSG = "mManageMobilePlanMessage"; 76 77 public WirelessSettings() { 78 super(null); 79 } 80 /** 81 * Invoked on each preference click in this hierarchy, overrides 82 * PreferenceActivity's implementation. Used to make sure we track the 83 * preference click events. 84 */ 85 @Override 86 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { 87 if (ensurePinRestrictedPreference(preference)) { 88 return true; 89 } 90 log("onPreferenceTreeClick: preference=" + preference); 91 if (preference == mAirplaneModePreference && Boolean.parseBoolean( 92 SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { 93 // In ECM mode launch ECM app dialog 94 startActivityForResult( 95 new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null), 96 REQUEST_CODE_EXIT_ECM); 97 return true; 98 } else if (preference == findPreference(KEY_MANAGE_MOBILE_PLAN)) { 99 onManageMobilePlanClick(); 100 } 101 // Let the intents be launched by the Preference manager 102 return super.onPreferenceTreeClick(preferenceScreen, preference); 103 } 104 105 private String mManageMobilePlanMessage; 106 private static final String CONNECTED_TO_PROVISIONING_NETWORK_ACTION 107 = "com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION"; 108 public void onManageMobilePlanClick() { 109 log("onManageMobilePlanClick:"); 110 mManageMobilePlanMessage = null; 111 Resources resources = getActivity().getResources(); 112 113 NetworkInfo ni = mCm.getProvisioningOrActiveNetworkInfo(); 114 if (mTm.hasIccCard() && (ni != null)) { 115 // Get provisioning URL 116 String url = mCm.getMobileProvisioningUrl(); 117 if (!TextUtils.isEmpty(url)) { 118 Intent intent = new Intent(CONNECTED_TO_PROVISIONING_NETWORK_ACTION); 119 intent.putExtra("EXTRA_URL", url); 120 Context context = getActivity().getBaseContext(); 121 context.sendBroadcast(intent); 122 mManageMobilePlanMessage = null; 123 } else { 124 // No provisioning URL 125 String operatorName = mTm.getSimOperatorName(); 126 if (TextUtils.isEmpty(operatorName)) { 127 // Use NetworkOperatorName as second choice in case there is no 128 // SPN (Service Provider Name on the SIM). Such as with T-mobile. 129 operatorName = mTm.getNetworkOperatorName(); 130 if (TextUtils.isEmpty(operatorName)) { 131 mManageMobilePlanMessage = resources.getString( 132 R.string.mobile_unknown_sim_operator); 133 } else { 134 mManageMobilePlanMessage = resources.getString( 135 R.string.mobile_no_provisioning_url, operatorName); 136 } 137 } else { 138 mManageMobilePlanMessage = resources.getString( 139 R.string.mobile_no_provisioning_url, operatorName); 140 } 141 } 142 } else if (mTm.hasIccCard() == false) { 143 // No sim card 144 mManageMobilePlanMessage = resources.getString(R.string.mobile_insert_sim_card); 145 } else { 146 // NetworkInfo is null, there is no connection 147 mManageMobilePlanMessage = resources.getString(R.string.mobile_connect_to_internet); 148 } 149 if (!TextUtils.isEmpty(mManageMobilePlanMessage)) { 150 log("onManageMobilePlanClick: message=" + mManageMobilePlanMessage); 151 showDialog(MANAGE_MOBILE_PLAN_DIALOG_ID); 152 } 153 } 154 155 @Override 156 public Dialog onCreateDialog(int dialogId) { 157 log("onCreateDialog: dialogId=" + dialogId); 158 switch (dialogId) { 159 case MANAGE_MOBILE_PLAN_DIALOG_ID: 160 return new AlertDialog.Builder(getActivity()) 161 .setMessage(mManageMobilePlanMessage) 162 .setCancelable(false) 163 .setPositiveButton(com.android.internal.R.string.ok, 164 new DialogInterface.OnClickListener() { 165 @Override 166 public void onClick(DialogInterface dialog, int id) { 167 log("MANAGE_MOBILE_PLAN_DIALOG.onClickListener id=" + id); 168 mManageMobilePlanMessage = null; 169 } 170 }) 171 .create(); 172 } 173 return super.onCreateDialog(dialogId); 174 } 175 176 private void log(String s) { 177 Log.d(TAG, s); 178 } 179 180 public static boolean isRadioAllowed(Context context, String type) { 181 if (!AirplaneModeEnabler.isAirplaneModeOn(context)) { 182 return true; 183 } 184 // Here we use the same logic in onCreate(). 185 String toggleable = Settings.Global.getString(context.getContentResolver(), 186 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 187 return toggleable != null && toggleable.contains(type); 188 } 189 190 @Override 191 public void onCreate(Bundle savedInstanceState) { 192 super.onCreate(savedInstanceState); 193 if (savedInstanceState != null) { 194 mManageMobilePlanMessage = savedInstanceState.getString(SAVED_MANAGE_MOBILE_PLAN_MSG); 195 } 196 log("onCreate: mManageMobilePlanMessage=" + mManageMobilePlanMessage); 197 198 mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 199 mTm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 200 201 addPreferencesFromResource(R.xml.wireless_settings); 202 203 final boolean isSecondaryUser = UserHandle.myUserId() != UserHandle.USER_OWNER; 204 205 final Activity activity = getActivity(); 206 mAirplaneModePreference = (CheckBoxPreference) findPreference(KEY_TOGGLE_AIRPLANE); 207 CheckBoxPreference nfc = (CheckBoxPreference) findPreference(KEY_TOGGLE_NFC); 208 PreferenceScreen androidBeam = (PreferenceScreen) findPreference(KEY_ANDROID_BEAM_SETTINGS); 209 CheckBoxPreference nsd = (CheckBoxPreference) findPreference(KEY_TOGGLE_NSD); 210 211 mAirplaneModeEnabler = new AirplaneModeEnabler(activity, mAirplaneModePreference); 212 mNfcEnabler = new NfcEnabler(activity, nfc, androidBeam); 213 214 // Remove NSD checkbox by default 215 getPreferenceScreen().removePreference(nsd); 216 //mNsdEnabler = new NsdEnabler(activity, nsd); 217 218 String toggleable = Settings.Global.getString(activity.getContentResolver(), 219 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 220 221 //enable/disable wimax depending on the value in config.xml 222 boolean isWimaxEnabled = !isSecondaryUser && this.getResources().getBoolean( 223 com.android.internal.R.bool.config_wimaxEnabled); 224 if (!isWimaxEnabled) { 225 PreferenceScreen root = getPreferenceScreen(); 226 Preference ps = (Preference) findPreference(KEY_WIMAX_SETTINGS); 227 if (ps != null) root.removePreference(ps); 228 } else { 229 if (toggleable == null || !toggleable.contains(Settings.Global.RADIO_WIMAX ) 230 && isWimaxEnabled) { 231 Preference ps = (Preference) findPreference(KEY_WIMAX_SETTINGS); 232 ps.setDependency(KEY_TOGGLE_AIRPLANE); 233 } 234 } 235 protectByRestrictions(KEY_WIMAX_SETTINGS); 236 237 // Manually set dependencies for Wifi when not toggleable. 238 if (toggleable == null || !toggleable.contains(Settings.Global.RADIO_WIFI)) { 239 findPreference(KEY_VPN_SETTINGS).setDependency(KEY_TOGGLE_AIRPLANE); 240 } 241 if (isSecondaryUser) { // Disable VPN 242 removePreference(KEY_VPN_SETTINGS); 243 } 244 protectByRestrictions(KEY_VPN_SETTINGS); 245 // Manually set dependencies for Bluetooth when not toggleable. 246 if (toggleable == null || !toggleable.contains(Settings.Global.RADIO_BLUETOOTH)) { 247 // No bluetooth-dependent items in the list. Code kept in case one is added later. 248 } 249 250 // Manually set dependencies for NFC when not toggleable. 251 if (toggleable == null || !toggleable.contains(Settings.Global.RADIO_NFC)) { 252 findPreference(KEY_TOGGLE_NFC).setDependency(KEY_TOGGLE_AIRPLANE); 253 findPreference(KEY_ANDROID_BEAM_SETTINGS).setDependency(KEY_TOGGLE_AIRPLANE); 254 } 255 256 // Remove NFC if its not available 257 mNfcAdapter = NfcAdapter.getDefaultAdapter(activity); 258 if (mNfcAdapter == null) { 259 getPreferenceScreen().removePreference(nfc); 260 getPreferenceScreen().removePreference(androidBeam); 261 mNfcEnabler = null; 262 } 263 264 // Remove Mobile Network Settings and Manage Mobile Plan if it's a wifi-only device. 265 if (isSecondaryUser || Utils.isWifiOnly(getActivity())) { 266 removePreference(KEY_MOBILE_NETWORK_SETTINGS); 267 removePreference(KEY_MANAGE_MOBILE_PLAN); 268 } 269 protectByRestrictions(KEY_MOBILE_NETWORK_SETTINGS); 270 protectByRestrictions(KEY_MANAGE_MOBILE_PLAN); 271 272 // Remove Airplane Mode settings if it's a stationary device such as a TV. 273 if (getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION)) { 274 removePreference(KEY_TOGGLE_AIRPLANE); 275 } 276 277 // Enable Proxy selector settings if allowed. 278 Preference mGlobalProxy = findPreference(KEY_PROXY_SETTINGS); 279 DevicePolicyManager mDPM = (DevicePolicyManager) 280 activity.getSystemService(Context.DEVICE_POLICY_SERVICE); 281 // proxy UI disabled until we have better app support 282 getPreferenceScreen().removePreference(mGlobalProxy); 283 mGlobalProxy.setEnabled(mDPM.getGlobalProxyAdmin() == null); 284 285 // Disable Tethering if it's not allowed or if it's a wifi-only device 286 ConnectivityManager cm = 287 (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE); 288 if (isSecondaryUser || !cm.isTetheringSupported()) { 289 getPreferenceScreen().removePreference(findPreference(KEY_TETHER_SETTINGS)); 290 } else { 291 Preference p = findPreference(KEY_TETHER_SETTINGS); 292 p.setTitle(Utils.getTetheringLabel(cm)); 293 } 294 protectByRestrictions(KEY_TETHER_SETTINGS); 295 296 // Enable link to CMAS app settings depending on the value in config.xml. 297 boolean isCellBroadcastAppLinkEnabled = this.getResources().getBoolean( 298 com.android.internal.R.bool.config_cellBroadcastAppLinks); 299 try { 300 if (isCellBroadcastAppLinkEnabled) { 301 PackageManager pm = getPackageManager(); 302 if (pm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver") 303 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { 304 isCellBroadcastAppLinkEnabled = false; // CMAS app disabled 305 } 306 } 307 } catch (IllegalArgumentException ignored) { 308 isCellBroadcastAppLinkEnabled = false; // CMAS app not installed 309 } 310 if (isSecondaryUser || !isCellBroadcastAppLinkEnabled) { 311 PreferenceScreen root = getPreferenceScreen(); 312 Preference ps = findPreference(KEY_CELL_BROADCAST_SETTINGS); 313 if (ps != null) root.removePreference(ps); 314 } 315 protectByRestrictions(KEY_CELL_BROADCAST_SETTINGS); 316 } 317 318 @Override 319 public void onResume() { 320 super.onResume(); 321 322 mAirplaneModeEnabler.resume(); 323 if (mNfcEnabler != null) { 324 mNfcEnabler.resume(); 325 } 326 if (mNsdEnabler != null) { 327 mNsdEnabler.resume(); 328 } 329 } 330 331 @Override 332 public void onSaveInstanceState(Bundle outState) { 333 super.onSaveInstanceState(outState); 334 335 if (!TextUtils.isEmpty(mManageMobilePlanMessage)) { 336 outState.putString(SAVED_MANAGE_MOBILE_PLAN_MSG, mManageMobilePlanMessage); 337 } 338 } 339 340 @Override 341 public void onPause() { 342 super.onPause(); 343 344 mAirplaneModeEnabler.pause(); 345 if (mNfcEnabler != null) { 346 mNfcEnabler.pause(); 347 } 348 if (mNsdEnabler != null) { 349 mNsdEnabler.pause(); 350 } 351 } 352 353 @Override 354 public void onActivityResult(int requestCode, int resultCode, Intent data) { 355 if (requestCode == REQUEST_CODE_EXIT_ECM) { 356 Boolean isChoiceYes = data.getBooleanExtra(EXIT_ECM_RESULT, false); 357 // Set Airplane mode based on the return value and checkbox state 358 mAirplaneModeEnabler.setAirplaneModeInECM(isChoiceYes, 359 mAirplaneModePreference.isChecked()); 360 } 361 super.onActivityResult(requestCode, resultCode, data); 362 } 363 364 @Override 365 protected int getHelpResource() { 366 return R.string.help_url_more_networks; 367 } 368} 369