diff options
Diffstat (limited to 'src')
22 files changed, 1017 insertions, 485 deletions
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java index 827af13..29be510 100644 --- a/src/com/android/settings/AccessibilitySettings.java +++ b/src/com/android/settings/AccessibilitySettings.java @@ -360,7 +360,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements extras.putBoolean(EXTRA_CHECKED, serviceEnabled); extras.putString(EXTRA_TITLE, title); - String description = info.getDescription(); + String description = info.loadDescription(getPackageManager()); if (TextUtils.isEmpty(description)) { description = getString(R.string.accessibility_service_default_description); } diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java index df421a2..88f7ae6 100644 --- a/src/com/android/settings/ChooseLockGeneric.java +++ b/src/com/android/settings/ChooseLockGeneric.java @@ -33,6 +33,8 @@ import android.widget.ListView; import com.android.internal.widget.LockPatternUtils; +import libcore.util.MutableBoolean; + public class ChooseLockGeneric extends PreferenceActivity { @Override @@ -167,23 +169,37 @@ public class ChooseLockGeneric extends PreferenceActivity { if (quality == -1) { // If caller didn't specify password quality, show UI and allow the user to choose. quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1); - quality = upgradeQuality(quality); + MutableBoolean allowBiometric = new MutableBoolean(false); + quality = upgradeQuality(quality, allowBiometric); final PreferenceScreen prefScreen = getPreferenceScreen(); if (prefScreen != null) { prefScreen.removeAll(); } addPreferencesFromResource(R.xml.security_settings_picker); - disableUnusablePreferences(quality); + disableUnusablePreferences(quality, allowBiometric); } else { updateUnlockMethodAndFinish(quality, false); } } - private int upgradeQuality(int quality) { + /** increases the quality if necessary, and returns whether biometric is allowed */ + private int upgradeQuality(int quality, MutableBoolean allowBiometric) { quality = upgradeQualityForDPM(quality); - quality = upgradeQualityForEncryption(quality); quality = upgradeQualityForKeyStore(quality); - return quality; + int encryptionQuality = upgradeQualityForEncryption(quality); + if (encryptionQuality > quality) { + //The first case checks whether biometric is allowed, prior to the user making + //their selection from the list + if (allowBiometric != null) { + allowBiometric.value = quality <= + DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; + } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) { + //When the user has selected biometric we shouldn't change that due to + //encryption + return quality; + } + } + return encryptionQuality; } private int upgradeQualityForDPM(int quality) { @@ -228,7 +244,7 @@ public class ChooseLockGeneric extends PreferenceActivity { * * @param quality the requested quality. */ - private void disableUnusablePreferences(final int quality) { + private void disableUnusablePreferences(final int quality, MutableBoolean allowBiometric) { final PreferenceScreen entries = getPreferenceScreen(); final boolean onlyShowFallback = getActivity().getIntent() .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false); @@ -245,7 +261,8 @@ public class ChooseLockGeneric extends PreferenceActivity { } else if (KEY_UNLOCK_SET_NONE.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } else if (KEY_UNLOCK_SET_BIOMETRIC_WEAK.equals(key)) { - enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; + enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK || + allowBiometric.value; visible = weakBiometricAvailable; // If not available, then don't show it. } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; @@ -311,7 +328,7 @@ public class ChooseLockGeneric extends PreferenceActivity { final boolean isFallback = getActivity().getIntent() .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false); - quality = upgradeQuality(quality); + quality = upgradeQuality(quality, null); if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { int minLength = mDPM.getPasswordMinimumLength(null); diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java index 41a4be5..ce3ad9d 100644 --- a/src/com/android/settings/CryptKeeperSettings.java +++ b/src/com/android/settings/CryptKeeperSettings.java @@ -159,7 +159,14 @@ public class CryptKeeperSettings extends Fragment { */ private boolean runKeyguardConfirmation(int request) { // 1. Confirm that we have a sufficient PIN/Password to continue - int quality = new LockPatternUtils(getActivity()).getActivePasswordQuality(); + LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity()); + int quality = lockPatternUtils.getActivePasswordQuality(); + if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK + && lockPatternUtils.isLockPasswordEnabled()) { + // Use the alternate as the quality. We expect this to be + // PASSWORD_QUALITY_SOMETHING(pattern) or PASSWORD_QUALITY_NUMERIC(PIN). + quality = lockPatternUtils.getKeyguardStoredPasswordQuality(); + } if (quality < MIN_PASSWORD_QUALITY) { return false; } diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java index 46d6c65..f33c11f 100644 --- a/src/com/android/settings/DataUsageSummary.java +++ b/src/com/android/settings/DataUsageSummary.java @@ -474,11 +474,7 @@ public class DataUsageSummary extends Fragment { case R.id.data_usage_menu_restrict_background: { final boolean restrictBackground = !item.isChecked(); if (restrictBackground) { - if (hasLimitedNetworks()) { - ConfirmRestrictFragment.show(this); - } else { - DeniedRestrictFragment.show(this); - } + ConfirmRestrictFragment.show(this); } else { // no confirmation to drop restriction setRestrictBackground(false); @@ -764,13 +760,8 @@ public class DataUsageSummary extends Fragment { && !getRestrictBackground() && isBandwidthControlEnabled() && hasMobileRadio(context)) { setPreferenceTitle(mAppRestrictView, R.string.data_usage_app_restrict_background); - if (hasLimitedNetworks()) { - setPreferenceSummary(mAppRestrictView, - getString(R.string.data_usage_app_restrict_background_summary)); - } else { - setPreferenceSummary(mAppRestrictView, - getString(R.string.data_usage_app_restrict_background_summary_disabled)); - } + setPreferenceSummary(mAppRestrictView, + getString(R.string.data_usage_app_restrict_background_summary)); mAppRestrictView.setVisibility(View.VISIBLE); mAppRestrict.setChecked(getAppRestrictBackground()); @@ -1037,16 +1028,10 @@ public class DataUsageSummary extends Fragment { final boolean restrictBackground = !mAppRestrict.isChecked(); if (restrictBackground) { - if (hasLimitedNetworks()) { - // enabling restriction; show confirmation dialog which - // eventually calls setRestrictBackground() once user - // confirms. - ConfirmAppRestrictFragment.show(DataUsageSummary.this); - } else { - // no limited networks; show dialog to guide user towards - // setting a network limit. doesn't mutate restrict state. - DeniedRestrictFragment.show(DataUsageSummary.this); - } + // enabling restriction; show confirmation dialog which + // eventually calls setRestrictBackground() once user + // confirms. + ConfirmAppRestrictFragment.show(DataUsageSummary.this); } else { setAppRestrictBackground(false); } diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java index 5887140..d2c227b 100644 --- a/src/com/android/settings/DisplaySettings.java +++ b/src/com/android/settings/DisplaySettings.java @@ -39,6 +39,8 @@ import android.util.Log; import android.view.IWindowManager; import android.view.Surface; +import com.android.settings.DreamSettings; + import java.util.ArrayList; public class DisplaySettings extends SettingsPreferenceFragment implements @@ -52,6 +54,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private static final String KEY_ACCELEROMETER = "accelerometer"; private static final String KEY_FONT_SIZE = "font_size"; private static final String KEY_NOTIFICATION_PULSE = "notification_pulse"; + private static final String KEY_SCREEN_SAVER = "screensaver"; private CheckBoxPreference mAccelerometer; private ListPreference mFontSizePref; @@ -60,6 +63,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private final Configuration mCurConfig = new Configuration(); private ListPreference mScreenTimeoutPreference; + private Preference mScreenSaverPreference; private ContentObserver mAccelerometerRotationObserver = new ContentObserver(new Handler()) { @Override @@ -78,6 +82,8 @@ public class DisplaySettings extends SettingsPreferenceFragment implements mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER); mAccelerometer.setPersistent(false); + mScreenSaverPreference = findPreference(KEY_SCREEN_SAVER); + mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT); final long currentTimeout = Settings.System.getLong(resolver, SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE); @@ -213,6 +219,14 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private void updateState() { updateAccelerometerRotationCheckbox(); readFontSizePreference(mFontSizePref); + updateScreenSaverSummary(); + } + + private void updateScreenSaverSummary() { + mScreenSaverPreference.setSummary( + DreamSettings.isScreenSaverEnabled(mScreenSaverPreference.getContext()) + ? R.string.screensaver_settings_summary_on + : R.string.screensaver_settings_summary_off); } private void updateAccelerometerRotationCheckbox() { diff --git a/src/com/android/settings/DreamComponentPreference.java b/src/com/android/settings/DreamComponentPreference.java new file mode 100644 index 0000000..b41ab3a --- /dev/null +++ b/src/com/android/settings/DreamComponentPreference.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings; + +import static android.provider.Settings.Secure.SCREENSAVER_COMPONENT; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.preference.Preference; +import android.provider.Settings; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ListAdapter; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class DreamComponentPreference extends Preference { + private static final String TAG = "DreamComponentPreference"; + + private static final boolean SHOW_DOCK_APPS_TOO = true; + + private final PackageManager pm; + private final ContentResolver resolver; + + public DreamComponentPreference(Context context, AttributeSet attrs) { + super(context, attrs); + pm = getContext().getPackageManager(); + resolver = getContext().getContentResolver(); + + refreshFromSettings(); + } + + private void refreshFromSettings() { + String component = Settings.Secure.getString(resolver, SCREENSAVER_COMPONENT); + if (component == null) { + component = getContext().getResources().getString( + com.android.internal.R.string.config_defaultDreamComponent); + } + if (component != null) { + ComponentName cn = ComponentName.unflattenFromString(component); + try { + setSummary(pm.getActivityInfo(cn, 0).loadLabel(pm)); + } catch (PackageManager.NameNotFoundException ex) { + setSummary("(unknown)"); + } + } + } + + final static Comparator<ResolveInfo> sResolveInfoComparator = new Comparator<ResolveInfo>() { + @Override + public int compare(ResolveInfo a, ResolveInfo b) { + int cmp = a.activityInfo.applicationInfo.packageName.compareTo( + b.activityInfo.applicationInfo.packageName); + if (cmp == 0) { + cmp = a.activityInfo.name.compareTo(b.activityInfo.name); + } + return cmp; + } + }; + + public class DreamListAdapter extends BaseAdapter implements ListAdapter { + private ArrayList<ResolveInfo> results; + private final LayoutInflater inflater; + + public DreamListAdapter(Context context) { + Intent choosy = new Intent(Intent.ACTION_MAIN) + .addCategory("android.intent.category.DREAM"); + + inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + results = new ArrayList<ResolveInfo>(pm.queryIntentActivities(choosy, 0)); + + // Group by package + Collections.sort(results, sResolveInfoComparator); + + if (SHOW_DOCK_APPS_TOO) { + choosy = new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_DESK_DOCK); + + List<ResolveInfo> dockApps = pm.queryIntentActivities(choosy, 0); + for (ResolveInfo app : dockApps) { + // do not insert duplicate packages + int pos = Collections.binarySearch(results, app, sResolveInfoComparator); + if (pos < 0) { + results.add(-1-pos, app); + } + } + } + } + + @Override + public int getCount() { + return results.size(); + } + + @Override + public Object getItem(int position) { + return results.get(position); + } + + @Override + public long getItemId (int position) { + return (long) position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View row = (convertView != null) + ? convertView + : inflater.inflate(R.layout.dream_picker_row, parent, false); + ResolveInfo ri = results.get(position); + ((TextView)row.findViewById(R.id.title)).setText(ri.loadLabel(pm)); + ((ImageView)row.findViewById(R.id.icon)).setImageDrawable(ri.loadIcon(pm)); + return row; + } + } + + @Override + protected void onClick() { + final DreamListAdapter list = new DreamListAdapter(getContext()); + AlertDialog alert = new AlertDialog.Builder(getContext()) + .setAdapter( + list, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + ResolveInfo ri = (ResolveInfo)list.getItem(which); + ActivityInfo act = ri.activityInfo; + ComponentName cn = new ComponentName( + act.applicationInfo.packageName, + act.name); + Intent intent = new Intent(Intent.ACTION_MAIN).setComponent(cn); + + setSummary(ri.loadLabel(pm)); + //getContext().startActivity(intent); + + Settings.Secure.putString(resolver, SCREENSAVER_COMPONENT, cn.flattenToString()); + } + }) + .create(); + alert.show(); + } +} diff --git a/src/com/android/settings/DreamSettings.java b/src/com/android/settings/DreamSettings.java new file mode 100644 index 0000000..d9953aa --- /dev/null +++ b/src/com/android/settings/DreamSettings.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings; + +import static android.provider.Settings.Secure.SCREENSAVER_ENABLED; +import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK; + +import android.app.ActionBar; +import android.app.Activity; +import android.app.ActivityManagerNative; +import android.app.admin.DevicePolicyManager; +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Configuration; +import android.database.ContentObserver; +import android.os.Bundle; +import android.os.Handler; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.preference.CheckBoxPreference; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceScreen; +import android.provider.Settings; +import android.util.Log; +import android.view.Gravity; +import android.view.IWindowManager; +import android.widget.CompoundButton; +import android.widget.Switch; + +import java.util.ArrayList; + +public class DreamSettings extends SettingsPreferenceFragment { + private static final String TAG = "DreamSettings"; + + private static final String KEY_ACTIVATE_ON_DOCK = "activate_on_dock"; + + private CheckBoxPreference mActivateOnDockPreference; + + private Switch mEnableSwitch; + private Enabler mEnabler; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + addPreferencesFromResource(R.xml.dream_settings); + + mActivateOnDockPreference = (CheckBoxPreference) findPreference(KEY_ACTIVATE_ON_DOCK); + + final Activity activity = getActivity(); + + mEnableSwitch = new Switch(activity); + + if (activity instanceof PreferenceActivity) { + PreferenceActivity preferenceActivity = (PreferenceActivity) activity; + // note: we do not check onIsHidingHeaders() or onIsMultiPane() because there's no + // switch in the left-hand pane to control this; we need to show the ON/OFF in our + // fragment every time + final int padding = activity.getResources().getDimensionPixelSize( + R.dimen.action_bar_switch_padding); + mEnableSwitch.setPadding(0, 0, padding, 0); + activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, + ActionBar.DISPLAY_SHOW_CUSTOM); + activity.getActionBar().setCustomView(mEnableSwitch, new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, + ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.RIGHT)); + activity.getActionBar().setTitle(R.string.screensaver_settings_title); + } + + mEnabler = new Enabler(activity, mEnableSwitch); + } + + public static boolean isScreenSaverEnabled(Context context) { + return 0 != Settings.Secure.getInt( + context.getContentResolver(), SCREENSAVER_ENABLED, 1); + } + + public static void setScreenSaverEnabled(Context context, boolean enabled) { + Settings.Secure.putInt( + context.getContentResolver(), SCREENSAVER_ENABLED, enabled ? 1 : 0); + } + + public static class Enabler implements CompoundButton.OnCheckedChangeListener { + private final Context mContext; + private Switch mSwitch; + + public Enabler(Context context, Switch switch_) { + mContext = context; + setSwitch(switch_); + } + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + setScreenSaverEnabled(mContext, isChecked); + } + public void setSwitch(Switch switch_) { + if (mSwitch == switch_) return; + if (mSwitch != null) mSwitch.setOnCheckedChangeListener(null); + mSwitch = switch_; + mSwitch.setOnCheckedChangeListener(this); + + final boolean enabled = isScreenSaverEnabled(mContext); + mSwitch.setChecked(enabled); + } + public void pause() { + mSwitch.setOnCheckedChangeListener(null); + } + public void resume() { + mSwitch.setOnCheckedChangeListener(this); + } + } + + @Override + public void onResume() { + if (mEnabler != null) { + mEnabler.resume(); + } + + final boolean currentActivateOnDock = 0 != Settings.Secure.getInt(getContentResolver(), + SCREENSAVER_ACTIVATE_ON_DOCK, 1); + mActivateOnDockPreference.setChecked(currentActivateOnDock); + super.onResume(); + } + + @Override + public void onPause() { + if (mEnabler != null) { + mEnabler.pause(); + } + + super.onPause(); + } + + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + if (preference == mActivateOnDockPreference) { + Settings.Secure.putInt(getContentResolver(), + SCREENSAVER_ACTIVATE_ON_DOCK, + mActivateOnDockPreference.isChecked() ? 1 : 0); + } + return super.onPreferenceTreeClick(preferenceScreen, preference); + } +} diff --git a/src/com/android/settings/DreamTesterPreference.java b/src/com/android/settings/DreamTesterPreference.java new file mode 100644 index 0000000..ccd6fc0 --- /dev/null +++ b/src/com/android/settings/DreamTesterPreference.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings; + +import static android.provider.Settings.Secure.SCREENSAVER_COMPONENT; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.preference.Preference; +import android.provider.Settings; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ListAdapter; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +public class DreamTesterPreference extends Preference { + private static final String TAG = "DreamTesterPreference"; + + private final PackageManager pm; + private final ContentResolver resolver; + + public DreamTesterPreference(Context context, AttributeSet attrs) { + super(context, attrs); + pm = getContext().getPackageManager(); + resolver = getContext().getContentResolver(); + } + + @Override + protected void onClick() { + String component = Settings.Secure.getString(resolver, SCREENSAVER_COMPONENT); + Log.v(TAG, "component=" + component); + if (component != null) { + ComponentName cn = ComponentName.unflattenFromString(component); + Log.v(TAG, "cn=" + cn); + Intent intent = new Intent(Intent.ACTION_MAIN) + .setComponent(cn) + .addFlags( + Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS + ) + .putExtra("android.dreams.TEST", true); + getContext().startActivity(intent); + } + } +} diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java index 867f733..a7621db 100644 --- a/src/com/android/settings/TetherSettings.java +++ b/src/com/android/settings/TetherSettings.java @@ -37,6 +37,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Environment; +import android.os.SystemProperties; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceScreen; @@ -476,6 +477,9 @@ public class TetherSettings extends SettingsPreferenceFragment } boolean isProvisioningNeeded() { + if (SystemProperties.getBoolean("net.tethering.noprovisioning", false)) { + return false; + } return mProvisionApp.length == 2; } diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java index 496947b..f4206eb 100644 --- a/src/com/android/settings/UserDictionarySettings.java +++ b/src/com/android/settings/UserDictionarySettings.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ListFragment; +import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -44,16 +45,13 @@ import android.widget.SectionIndexer; import android.widget.SimpleCursorAdapter; import android.widget.TextView; -import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment; +import com.android.settings.inputmethod.UserDictionaryAddWordActivity; import java.util.Locale; -public class UserDictionarySettings extends ListFragment implements DialogCreatable { +public class UserDictionarySettings extends ListFragment { private static final String TAG = "UserDictionarySettings"; - private static final String INSTANCE_KEY_DIALOG_EDITING_WORD = "DIALOG_EDITING_WORD"; - private static final String INSTANCE_KEY_ADDED_WORD = "DIALOG_ADDED_WORD"; - private static final String[] QUERY_PROJECTION = { UserDictionary.Words._ID, UserDictionary.Words.WORD }; @@ -70,26 +68,12 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata private static final String DELETE_SELECTION = UserDictionary.Words.WORD + "=?"; - private static final String EXTRA_WORD = "word"; - private static final int OPTIONS_MENU_ADD = Menu.FIRST; - private static final int DIALOG_ADD_OR_EDIT = 0; - - private static final int FREQUENCY_FOR_USER_DICTIONARY_ADDS = 250; - - /** The word being edited in the dialog (null means the user is adding a word). */ - private String mDialogEditingWord; - private Cursor mCursor; protected String mLocale; - private boolean mAddedWordAlready; - private boolean mAutoReturn; - - private SettingsDialogFragment mDialogFragment; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -135,31 +119,6 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata setHasOptionsMenu(true); - if (savedInstanceState != null) { - mDialogEditingWord = savedInstanceState.getString(INSTANCE_KEY_DIALOG_EDITING_WORD); - mAddedWordAlready = savedInstanceState.getBoolean(INSTANCE_KEY_ADDED_WORD, false); - } - } - - @Override - public void onResume() { - super.onResume(); - final Intent intent = getActivity().getIntent(); - if (!mAddedWordAlready - && intent.getAction().equals("com.android.settings.USER_DICTIONARY_INSERT")) { - final String word = intent.getStringExtra(EXTRA_WORD); - mAutoReturn = true; - if (word != null) { - showAddOrEditDialog(word); - } - } - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(INSTANCE_KEY_DIALOG_EDITING_WORD, mDialogEditingWord); - outState.putBoolean(INSTANCE_KEY_ADDED_WORD, mAddedWordAlready); } private Cursor createCursor(final String locale) { @@ -216,9 +175,18 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata return true; } - private void showAddOrEditDialog(String editingWord) { - mDialogEditingWord = editingWord; - showDialog(DIALOG_ADD_OR_EDIT); + /** + * Add or edit a word. If editingWord is null, it's an add; otherwise, it's an edit. + * @param editingWord the word to edit, or null if it's an add. + */ + private void showAddOrEditDialog(final String editingWord) { + final Intent intent = new Intent(null == editingWord + ? UserDictionaryAddWordActivity.MODE_INSERT_ACTION + : UserDictionaryAddWordActivity.MODE_EDIT_ACTION); + // The following are fine if they are null + intent.putExtra(UserDictionaryAddWordActivity.EXTRA_WORD, editingWord); + intent.putExtra(UserDictionaryAddWordActivity.EXTRA_LOCALE, mLocale); + startActivity(intent); } private String getWord(int position) { @@ -231,81 +199,8 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata mCursor.getColumnIndexOrThrow(UserDictionary.Words.WORD)); } - @Override - public Dialog onCreateDialog(int id) { - final Activity activity = getActivity(); - final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity); - final LayoutInflater inflater = LayoutInflater.from(dialogBuilder.getContext()); - final View content = inflater.inflate(R.layout.dialog_edittext, null); - final EditText editText = (EditText) content.findViewById(R.id.edittext); - editText.setText(mDialogEditingWord); - // No prediction in soft keyboard mode. TODO: Create a better way to disable prediction - editText.setInputType(InputType.TYPE_CLASS_TEXT - | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); - - AlertDialog dialog = dialogBuilder - .setTitle(mDialogEditingWord != null - ? R.string.user_dict_settings_edit_dialog_title - : R.string.user_dict_settings_add_dialog_title) - .setView(content) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - onAddOrEditFinished(editText.getText().toString()); - if (mAutoReturn) activity.onBackPressed(); - }}) - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (mAutoReturn) activity.onBackPressed(); - }}) - .create(); - dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN | - WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); - return dialog; - } - - private void showDialog(int dialogId) { - if (mDialogFragment != null) { - Log.e(TAG, "Old dialog fragment not null!"); - } - mDialogFragment = new SettingsDialogFragment(this, dialogId); - mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId)); - } - - private void onAddOrEditFinished(String word) { - if (mDialogEditingWord != null) { - // The user was editing a word, so do a delete/add - deleteWord(mDialogEditingWord); - } - - // Disallow duplicates - deleteWord(word); - - // TODO: present UI for picking whether to add word to all locales, or current. - if (null == mLocale) { - // Null means insert with the default system locale. - UserDictionary.Words.addWord(getActivity(), word.toString(), - FREQUENCY_FOR_USER_DICTIONARY_ADDS, UserDictionary.Words.LOCALE_TYPE_CURRENT); - } else if ("".equals(mLocale)) { - // Empty string means insert for all languages. - UserDictionary.Words.addWord(getActivity(), word.toString(), - FREQUENCY_FOR_USER_DICTIONARY_ADDS, UserDictionary.Words.LOCALE_TYPE_ALL); - } else { - // TODO: fix the framework so that it can accept a locale when we add a word - // to the user dictionary instead of querying the system locale. - final Locale prevLocale = Locale.getDefault(); - Locale.setDefault(Utils.createLocaleFromString(mLocale)); - UserDictionary.Words.addWord(getActivity(), word.toString(), - FREQUENCY_FOR_USER_DICTIONARY_ADDS, UserDictionary.Words.LOCALE_TYPE_CURRENT); - Locale.setDefault(prevLocale); - } - if (null != mCursor && !mCursor.requery()) { - throw new IllegalStateException("can't requery on already-closed cursor."); - } - mAddedWordAlready = true; - } - - private void deleteWord(String word) { - getActivity().getContentResolver().delete( + public static void deleteWord(final String word, final ContentResolver resolver) { + resolver.delete( UserDictionary.Words.CONTENT_URI, DELETE_SELECTION, new String[] { word }); } @@ -355,7 +250,8 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata } public void onClick(View v) { - mSettings.deleteWord((String) v.getTag()); + UserDictionarySettings.deleteWord((String) v.getTag(), + mSettings.getActivity().getContentResolver()); } } } diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java index 13f6902..6ae3275 100644 --- a/src/com/android/settings/WirelessSettings.java +++ b/src/com/android/settings/WirelessSettings.java @@ -37,7 +37,6 @@ import android.widget.Switch; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; import com.android.settings.nfc.NfcEnabler; -import com.android.settings.wifi.p2p.WifiP2pEnabler; public class WirelessSettings extends SettingsPreferenceFragment { @@ -46,7 +45,6 @@ public class WirelessSettings extends SettingsPreferenceFragment { private static final String KEY_WIMAX_SETTINGS = "wimax_settings"; private static final String KEY_ANDROID_BEAM_SETTINGS = "android_beam_settings"; private static final String KEY_VPN_SETTINGS = "vpn_settings"; - private static final String KEY_TOGGLE_WIFI_P2P = "toggle_wifi_p2p"; private static final String KEY_WIFI_P2P_SETTINGS = "wifi_p2p_settings"; private static final String KEY_TETHER_SETTINGS = "tether_settings"; private static final String KEY_PROXY_SETTINGS = "proxy_settings"; @@ -60,8 +58,6 @@ public class WirelessSettings extends SettingsPreferenceFragment { private NfcEnabler mNfcEnabler; private NfcAdapter mNfcAdapter; - private WifiP2pEnabler mWifiP2pEnabler; - /** * Invoked on each preference click in this hierarchy, overrides * PreferenceActivity's implementation. Used to make sure we track the @@ -102,8 +98,6 @@ public class WirelessSettings extends SettingsPreferenceFragment { CheckBoxPreference nfc = (CheckBoxPreference) findPreference(KEY_TOGGLE_NFC); PreferenceScreen androidBeam = (PreferenceScreen) findPreference(KEY_ANDROID_BEAM_SETTINGS); - CheckBoxPreference wifiP2p = (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI_P2P); - mAirplaneModeEnabler = new AirplaneModeEnabler(activity, mAirplaneModePreference); mNfcEnabler = new NfcEnabler(activity, nfc, androidBeam); @@ -156,11 +150,8 @@ public class WirelessSettings extends SettingsPreferenceFragment { WifiP2pManager p2p = (WifiP2pManager) activity.getSystemService(Context.WIFI_P2P_SERVICE); if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) { - getPreferenceScreen().removePreference(wifiP2p); - } else { - mWifiP2pEnabler = new WifiP2pEnabler(activity, wifiP2p); + getPreferenceScreen().removePreference(findPreference(KEY_WIFI_P2P_SETTINGS)); } - getPreferenceScreen().removePreference(findPreference(KEY_WIFI_P2P_SETTINGS)); // Enable Proxy selector settings if allowed. Preference mGlobalProxy = findPreference(KEY_PROXY_SETTINGS); @@ -189,10 +180,6 @@ public class WirelessSettings extends SettingsPreferenceFragment { if (mNfcEnabler != null) { mNfcEnabler.resume(); } - - if (mWifiP2pEnabler != null) { - mWifiP2pEnabler.resume(); - } } @Override @@ -203,10 +190,6 @@ public class WirelessSettings extends SettingsPreferenceFragment { if (mNfcEnabler != null) { mNfcEnabler.pause(); } - - if (mWifiP2pEnabler != null) { - mWifiP2pEnabler.pause(); - } } @Override diff --git a/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java b/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java index 952146d..28b8616 100644 --- a/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java +++ b/src/com/android/settings/inputmethod/CheckBoxAndSettingsPreference.java @@ -34,8 +34,7 @@ public class CheckBoxAndSettingsPreference extends CheckBoxPreference { private SettingsPreferenceFragment mFragment; private TextView mTitleText; private TextView mSummaryText; - private View mCheckBox; - private ImageView mSetingsButton; + private ImageView mSettingsButton; private Intent mSettingsIntent; public CheckBoxAndSettingsPreference(Context context, AttributeSet attrs) { @@ -47,28 +46,28 @@ public class CheckBoxAndSettingsPreference extends CheckBoxPreference { @Override protected void onBindView(View view) { super.onBindView(view); - mCheckBox = view.findViewById(R.id.inputmethod_pref); - mCheckBox.setOnClickListener( + View textLayout = view.findViewById(R.id.inputmethod_pref); + textLayout.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { onCheckBoxClicked(); } }); - mSetingsButton = (ImageView)view.findViewById(R.id.inputmethod_settings); + + mSettingsButton = (ImageView) view.findViewById(R.id.inputmethod_settings); mTitleText = (TextView)view.findViewById(android.R.id.title); mSummaryText = (TextView)view.findViewById(android.R.id.summary); - mSetingsButton.setOnClickListener( + mSettingsButton.setOnClickListener( new OnClickListener() { @Override - public void onClick(View arg0) { - onSettingsButtonClicked(arg0); + public void onClick(View clickedView) { + onSettingsButtonClicked(); } }); enableSettingsButton(); } - @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); @@ -88,23 +87,23 @@ public class CheckBoxAndSettingsPreference extends CheckBoxPreference { } } - protected void onSettingsButtonClicked(View arg0) { + protected void onSettingsButtonClicked() { if (mFragment != null && mSettingsIntent != null) { mFragment.startActivity(mSettingsIntent); } } private void enableSettingsButton() { - if (mSetingsButton != null) { + if (mSettingsButton != null) { if (mSettingsIntent == null) { - mSetingsButton.setVisibility(View.GONE); + mSettingsButton.setVisibility(View.GONE); } else { final boolean checked = isChecked(); - mSetingsButton.setEnabled(checked); - mSetingsButton.setClickable(checked); - mSetingsButton.setFocusable(checked); + mSettingsButton.setEnabled(checked); + mSettingsButton.setClickable(checked); + mSettingsButton.setFocusable(checked); if (!checked) { - mSetingsButton.setAlpha(DISABLED_ALPHA); + mSettingsButton.setAlpha(DISABLED_ALPHA); } } } diff --git a/src/com/android/settings/inputmethod/UserDictionaryAddWordActivity.java b/src/com/android/settings/inputmethod/UserDictionaryAddWordActivity.java new file mode 100644 index 0000000..13c226f --- /dev/null +++ b/src/com/android/settings/inputmethod/UserDictionaryAddWordActivity.java @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.inputmethod; + +import com.android.settings.R; +import com.android.settings.UserDictionarySettings; +import com.android.settings.Utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import android.animation.LayoutTransition; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.provider.UserDictionary; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; + +public class UserDictionaryAddWordActivity extends Activity + implements AdapterView.OnItemSelectedListener { + public static final String EXTRA_WORD = "word"; + public static final String EXTRA_LOCALE = "locale"; + private static final int FREQUENCY_FOR_USER_DICTIONARY_ADDS = 250; + + private static final String STATE_KEY_IS_OPEN = "isOpen"; + private static final String STATE_KEY_WORD = "word"; + private static final String STATE_KEY_LOCALE = "locale"; + + public static final String MODE_EDIT_ACTION = "com.android.settings.USER_DICTIONARY_EDIT"; + public static final String MODE_INSERT_ACTION = "com.android.settings.USER_DICTIONARY_INSERT"; + private static final int MODE_EDIT = 0; + private static final int MODE_INSERT = 1; + + private static final int[] IDS_SHOWN_ONLY_IN_MORE_OPTIONS_MODE = { + R.id.user_dictionary_add_word_label, + R.id.user_dictionary_add_shortcut_label, + R.id.user_dictionary_add_locale_label, + R.id.user_dictionary_settings_add_dialog_shortcut, + R.id.user_dictionary_settings_add_dialog_locale, + }; + + private EditText mEditText; + private int mMode; // Either MODE_EDIT or MODE_INSERT + private String mOldWord; + private String mLocale; // may not be null: will be converted to default locale if received null + + private boolean mIsShowingMoreOptions = false; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.user_dictionary_add_word); + final Intent intent = getIntent(); + final String action = intent.getAction(); + if (MODE_EDIT_ACTION.equals(action)) { + mMode = MODE_EDIT; + } else if (MODE_INSERT_ACTION.equals(action)) { + mMode = MODE_INSERT; + } else { + // Can never come here because we only support these two actions in the manifest + throw new RuntimeException("Unsupported action: " + action); + } + + String savedWord = null; + String savedLocale = null; + if (null != savedInstanceState) { + mIsShowingMoreOptions = + savedInstanceState.getBoolean(STATE_KEY_IS_OPEN, mIsShowingMoreOptions); + savedWord = savedInstanceState.getString(STATE_KEY_WORD); + savedLocale = savedInstanceState.getString(STATE_KEY_LOCALE); + } + + mOldWord = intent.getStringExtra(EXTRA_WORD); + if (null != savedLocale) { + mLocale = savedLocale; + } else { + final String locale = intent.getStringExtra(EXTRA_LOCALE); // this may be null + mLocale = null == locale ? Locale.getDefault().toString() : locale; + } + mEditText = (EditText)findViewById(R.id.user_dictionary_add_word_text); + if (null != savedWord) { + mEditText.setText(savedWord); + mEditText.setSelection(savedWord.length()); + } else if (null != mOldWord) { + mEditText.setText(mOldWord); + mEditText.setSelection(mOldWord.length()); + } + + if (mIsShowingMoreOptions) { + onClickMoreOptions(findViewById(R.id.user_dictionary_settings_add_dialog_more_options)); + } + + // TODO: The following code enables layout transition for eye-candy, but there is still + // a jankiness issue with the window moving on one frame, resizing suddenly on the next, + // and animation only starting afterwards on children. + final ViewGroup v = (ViewGroup)findViewById(R.id.user_dictionary_add_word_grid); + final LayoutTransition transition = new LayoutTransition(); + transition.setStartDelay(LayoutTransition.APPEARING, 0); + v.setLayoutTransition(transition); + } + + @Override + public void onSaveInstanceState(final Bundle outState) { + outState.putBoolean(STATE_KEY_IS_OPEN, mIsShowingMoreOptions); + outState.putString(STATE_KEY_WORD, mEditText.getText().toString()); + outState.putString(STATE_KEY_LOCALE, mLocale); + } + + public void onClickCancel(final View v) { + finish(); + } + + public void onClickConfirm(final View v) { + if (MODE_EDIT == mMode && !TextUtils.isEmpty(mOldWord)) { + UserDictionarySettings.deleteWord(mOldWord, this.getContentResolver()); + } + final String newWord = mEditText.getText().toString(); + if (TextUtils.isEmpty(newWord)) { + // If the word is somehow empty, don't insert it. + // TODO: grey out the Ok button when the text is empty? + finish(); + return; + } + // Disallow duplicates. + // TODO: Redefine the logic when we support shortcuts. + UserDictionarySettings.deleteWord(newWord, this.getContentResolver()); + + if (TextUtils.isEmpty(mLocale)) { + // Empty string means insert for all languages. + UserDictionary.Words.addWord(this, newWord.toString(), + FREQUENCY_FOR_USER_DICTIONARY_ADDS, UserDictionary.Words.LOCALE_TYPE_ALL); + } else { + // TODO: fix the framework so that it can accept a locale when we add a word + // to the user dictionary instead of querying the system locale. + final Locale prevLocale = Locale.getDefault(); + Locale.setDefault(Utils.createLocaleFromString(mLocale)); + UserDictionary.Words.addWord(this, newWord.toString(), + FREQUENCY_FOR_USER_DICTIONARY_ADDS, UserDictionary.Words.LOCALE_TYPE_CURRENT); + Locale.setDefault(prevLocale); + } + finish(); + } + + private static class LocaleRenderer { + private final String mLocaleString; + private final String mDescription; + // LocaleString may NOT be null. + public LocaleRenderer(final Context context, final String localeString) { + mLocaleString = localeString; + if (null == localeString) { + mDescription = context.getString(R.string.user_dict_settings_more_languages); + } else if ("".equals(localeString)) { + mDescription = context.getString(R.string.user_dict_settings_all_languages); + } else { + mDescription = Utils.createLocaleFromString(localeString).getDisplayName(); + } + } + @Override + public String toString() { + return mDescription; + } + public String getLocaleString() { + return mLocaleString; + } + } + + private static void addLocaleDisplayNameToList(final Context context, + final List<LocaleRenderer> list, final String locale) { + if (null != locale) { + list.add(new LocaleRenderer(context, locale)); + } + } + + public void onClickMoreOptions(final View v) { + for (final int idToShow : IDS_SHOWN_ONLY_IN_MORE_OPTIONS_MODE) { + final View viewToShow = findViewById(idToShow); + viewToShow.setVisibility(View.VISIBLE); + } + findViewById(R.id.user_dictionary_settings_add_dialog_more_options) + .setVisibility(View.GONE); + findViewById(R.id.user_dictionary_settings_add_dialog_less_options) + .setVisibility(View.VISIBLE); + + final Set<String> locales = UserDictionaryList.getUserDictionaryLocalesList(this); + // Remove our locale if it's in, because we're always gonna put it at the top + locales.remove(mLocale); // mLocale may not be null + final String systemLocale = Locale.getDefault().toString(); + // The system locale should be inside. We want it at the 2nd spot. + locales.remove(systemLocale); // system locale may not be null + locales.remove(""); // Remove the empty string if it's there + final ArrayList<LocaleRenderer> localesList = new ArrayList<LocaleRenderer>(); + // Add the passed locale, then the system locale at the top of the list. Add an + // "all languages" entry at the bottom of the list. + addLocaleDisplayNameToList(this, localesList, mLocale); + if (!systemLocale.equals(mLocale)) { + addLocaleDisplayNameToList(this, localesList, systemLocale); + } + for (final String l : locales) { + // TODO: sort in unicode order + addLocaleDisplayNameToList(this, localesList, l); + } + localesList.add(new LocaleRenderer(this, "")); // meaning: all languages + localesList.add(new LocaleRenderer(this, null)); // meaning: select another locale + final Spinner localeSpinner = + (Spinner)findViewById(R.id.user_dictionary_settings_add_dialog_locale); + final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<LocaleRenderer>(this, + android.R.layout.simple_spinner_item, localesList); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + localeSpinner.setAdapter(adapter); + localeSpinner.setOnItemSelectedListener(this); + mIsShowingMoreOptions = true; + } + + public void onClickLessOptions(final View v) { + for (final int idToHide : IDS_SHOWN_ONLY_IN_MORE_OPTIONS_MODE) { + final View viewToHide = findViewById(idToHide); + viewToHide.setVisibility(View.GONE); + } + findViewById(R.id.user_dictionary_settings_add_dialog_more_options) + .setVisibility(View.VISIBLE); + findViewById(R.id.user_dictionary_settings_add_dialog_less_options) + .setVisibility(View.GONE); + mIsShowingMoreOptions = false; + } + + @Override + public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, + final long id) { + final LocaleRenderer locale = (LocaleRenderer)parent.getItemAtPosition(pos); + mLocale = locale.getLocaleString(); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + // I'm not sure we can come here, but if we do, that's the right thing to do. + final Intent intent = getIntent(); + final String locale = intent.getStringExtra(EXTRA_LOCALE); // this may be null + mLocale = null == locale ? Locale.getDefault().toString() : locale; + } +} diff --git a/src/com/android/settings/net/NetworkPolicyEditor.java b/src/com/android/settings/net/NetworkPolicyEditor.java index 5ba8ca4..c9407ce 100644 --- a/src/com/android/settings/net/NetworkPolicyEditor.java +++ b/src/com/android/settings/net/NetworkPolicyEditor.java @@ -146,7 +146,7 @@ public class NetworkPolicyEditor { final int cycleDay = time.monthDay; return new NetworkPolicy( - template, cycleDay, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER); + template, cycleDay, WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, true); } public int getPolicyCycleDay(NetworkTemplate template) { @@ -251,7 +251,7 @@ public class NetworkPolicyEditor { mPolicies.remove(policy4g); mPolicies.add( new NetworkPolicy(templateAll, restrictive.cycleDay, restrictive.warningBytes, - restrictive.limitBytes, SNOOZE_NEVER)); + restrictive.limitBytes, SNOOZE_NEVER, restrictive.metered)); return true; } else if (!beforeSplit && split) { @@ -260,10 +260,10 @@ public class NetworkPolicyEditor { mPolicies.remove(policyAll); mPolicies.add( new NetworkPolicy(template3g, policyAll.cycleDay, policyAll.warningBytes, - policyAll.limitBytes, SNOOZE_NEVER)); + policyAll.limitBytes, SNOOZE_NEVER, policyAll.metered)); mPolicies.add( new NetworkPolicy(template4g, policyAll.cycleDay, policyAll.warningBytes, - policyAll.limitBytes, SNOOZE_NEVER)); + policyAll.limitBytes, SNOOZE_NEVER, policyAll.metered)); return true; } else { return false; diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java index 517eade..fbcdb4f 100644 --- a/src/com/android/settings/tts/TextToSpeechSettings.java +++ b/src/com/android/settings/tts/TextToSpeechSettings.java @@ -192,23 +192,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements checkVoiceData(mCurrentEngine); } - private void maybeUpdateTtsLanguage(String currentEngine) { - if (currentEngine != null && mTts != null) { - final String localeString = mEnginesHelper.getLocalePrefForEngine( - currentEngine); - if (localeString != null) { - final String[] locale = TtsEngines.parseLocalePref(localeString); - final Locale newLocale = new Locale(locale[0], locale[1], locale[2]); - final Locale engineLocale = mTts.getLanguage(); - - if (!newLocale.equals(engineLocale)) { - if (DBG) Log.d(TAG, "Loading language ahead of sample check : " + locale); - mTts.setLanguage(newLocale); - } - } - } - } - /** * Ask the current default engine to return a string of sample text to be * spoken to the user. @@ -218,7 +201,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements if (TextUtils.isEmpty(currentEngine)) currentEngine = mTts.getDefaultEngine(); - maybeUpdateTtsLanguage(currentEngine); Locale currentLocale = mTts.getLanguage(); // TODO: This is currently a hidden private API. The intent extras diff --git a/src/com/android/settings/tts/TtsEngineSettingsFragment.java b/src/com/android/settings/tts/TtsEngineSettingsFragment.java index 18d1fdb..fcc2f2e 100644 --- a/src/com/android/settings/tts/TtsEngineSettingsFragment.java +++ b/src/com/android/settings/tts/TtsEngineSettingsFragment.java @@ -51,6 +51,25 @@ public class TtsEngineSettingsFragment extends SettingsPreferenceFragment implem private Preference mInstallVoicesPreference; private Intent mEngineSettingsIntent; + private TextToSpeech mTts; + + private final TextToSpeech.OnInitListener mTtsInitListener = new TextToSpeech.OnInitListener() { + @Override + public void onInit(int status) { + if (status != TextToSpeech.SUCCESS) { + finishFragment(); + } else { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + mLocalePreference.setEnabled(true); + updateVoiceDetails(); + } + }); + } + } + }; + public TtsEngineSettingsFragment() { super(); } @@ -83,7 +102,15 @@ public class TtsEngineSettingsFragment extends SettingsPreferenceFragment implem } mInstallVoicesPreference.setEnabled(false); - updateVoiceDetails(); + mLocalePreference.setEnabled(false); + mTts = new TextToSpeech(getActivity().getApplicationContext(), mTtsInitListener, + getEngineName()); + } + + @Override + public void onDestroy() { + mTts.shutdown(); + super.onDestroy(); } private void updateVoiceDetails() { @@ -153,8 +180,7 @@ public class TtsEngineSettingsFragment extends SettingsPreferenceFragment implem mLocalePreference.setValueIndex(selectedLanguageIndex); } else { mLocalePreference.setValueIndex(0); - mEnginesHelper.updateLocalePrefForEngine(getEngineName(), - availableLangs.get(0)); + updateLanguageTo(availableLangs.get(0)); } } @@ -191,13 +217,23 @@ public class TtsEngineSettingsFragment extends SettingsPreferenceFragment implem @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (preference == mLocalePreference) { - mEnginesHelper.updateLocalePrefForEngine(getEngineName(), (String) newValue); + updateLanguageTo((String) newValue); return true; } return false; } + private void updateLanguageTo(String locale) { + mEnginesHelper.updateLocalePrefForEngine(getEngineName(), locale); + if (getEngineName().equals(mTts.getCurrentEngine())) { + String[] localeArray = TtsEngines.parseLocalePref(locale); + if (localeArray != null) { + mTts.setLanguage(new Locale(localeArray[0], localeArray[1], localeArray[2])); + } + } + } + private String getEngineName() { return getArguments().getString(TtsEnginePreference.FRAGMENT_ARGS_NAME); } diff --git a/src/com/android/settings/vpn2/VpnDialog.java b/src/com/android/settings/vpn2/VpnDialog.java index aaae887..ca85d99 100644 --- a/src/com/android/settings/vpn2/VpnDialog.java +++ b/src/com/android/settings/vpn2/VpnDialog.java @@ -102,8 +102,10 @@ class VpnDialog extends AlertDialog implements TextWatcher, mName.setText(mProfile.name); mType.setSelection(mProfile.type); mServer.setText(mProfile.server); - mUsername.setText(mProfile.username); - mPassword.setText(mProfile.password); + if (mProfile.saveLogin) { + mUsername.setText(mProfile.username); + mPassword.setText(mProfile.password); + } mSearchDomains.setText(mProfile.searchDomains); mDnsServers.setText(mProfile.dnsServers); mRoutes.setText(mProfile.routes); @@ -111,7 +113,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, mL2tpSecret.setText(mProfile.l2tpSecret); mIpsecIdentifier.setText(mProfile.ipsecIdentifier); mIpsecSecret.setText(mProfile.ipsecSecret); - loadCertificates(mIpsecUserCert, Credentials.USER_CERTIFICATE, + loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY, 0, mProfile.ipsecUserCert); loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE, R.string.vpn_no_ca_cert, mProfile.ipsecCaCert); diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 2f8ae54..3852cc9 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -271,7 +271,7 @@ public class WifiConfigController implements TextWatcher, } /* show submit button if password, ip and proxy settings are valid */ - private void enableSubmitIfAppropriate() { + void enableSubmitIfAppropriate() { Button submit = mConfigUi.getSubmitButton(); if (submit == null) return; boolean enabled = false; diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index f980d0c..82b0cc6 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -56,6 +56,9 @@ class WifiDialog extends AlertDialog implements WifiConfigUiBase { setInverseBackgroundForced(true); mController = new WifiConfigController(this, mView, mAccessPoint, mEdit); super.onCreate(savedInstanceState); + /* During creation, the submit button can be unavailable to determine + * visibility. Right after creation, update button visibility */ + mController.enableSubmitIfAppropriate(); } @Override diff --git a/src/com/android/settings/wifi/p2p/WifiP2pDialog.java b/src/com/android/settings/wifi/p2p/WifiP2pDialog.java deleted file mode 100644 index e688905..0000000 --- a/src/com/android/settings/wifi/p2p/WifiP2pDialog.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.wifi.p2p; - -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.net.wifi.WpsInfo; -import android.net.wifi.p2p.WifiP2pConfig; -import android.net.wifi.p2p.WifiP2pDevice; -import android.os.Bundle; -import android.view.View; -import android.widget.AdapterView; -import android.widget.CheckBox; -import android.widget.Spinner; -import android.widget.TextView; - -import com.android.settings.R; - -/** - * Dialog to setup a p2p connection - */ -public class WifiP2pDialog extends AlertDialog implements AdapterView.OnItemSelectedListener { - - static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE; - - private final DialogInterface.OnClickListener mListener; - - private View mView; - private TextView mDeviceName; - private TextView mDeviceAddress; - - /* These values come from "wifi_p2p_wps_setup" resource array */ - private static final int WPS_PBC = 0; - private static final int WPS_KEYPAD = 1; - private static final int WPS_DISPLAY = 2; - - private int mWpsSetupIndex = WPS_PBC; //default is pbc - - WifiP2pDevice mDevice; - - public WifiP2pDialog(Context context, DialogInterface.OnClickListener listener, - WifiP2pDevice device) { - super(context); - mListener = listener; - mDevice = device; - } - - public WifiP2pConfig getConfig() { - WifiP2pConfig config = new WifiP2pConfig(); - config.deviceAddress = mDeviceAddress.getText().toString(); - config.wps = new WpsInfo(); - switch (mWpsSetupIndex) { - case WPS_PBC: - config.wps.setup = WpsInfo.PBC; - break; - case WPS_KEYPAD: - config.wps.setup = WpsInfo.KEYPAD; - config.wps.pin = ((TextView) mView.findViewById(R.id.wps_pin)). - getText().toString(); - break; - case WPS_DISPLAY: - config.wps.setup = WpsInfo.DISPLAY; - break; - default: - config.wps.setup = WpsInfo.PBC; - break; - } - return config; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - - mView = getLayoutInflater().inflate(R.layout.wifi_p2p_dialog, null); - Spinner mWpsSetup = ((Spinner) mView.findViewById(R.id.wps_setup)); - - setView(mView); - setInverseBackgroundForced(true); - - Context context = getContext(); - - setTitle(R.string.wifi_p2p_settings_title); - mDeviceName = (TextView) mView.findViewById(R.id.device_name); - mDeviceAddress = (TextView) mView.findViewById(R.id.device_address); - - setButton(BUTTON_SUBMIT, context.getString(R.string.wifi_connect), mListener); - setButton(DialogInterface.BUTTON_NEGATIVE, - context.getString(R.string.wifi_cancel), mListener); - - if (mDevice != null) { - mDeviceName.setText(mDevice.deviceName); - mDeviceAddress.setText(mDevice.deviceAddress); - mWpsSetup.setSelection(mWpsSetupIndex); //keep pbc as default - } - - mWpsSetup.setOnItemSelectedListener(this); - - super.onCreate(savedInstanceState); - } - - @Override - public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { - mWpsSetupIndex = position; - - if (mWpsSetupIndex == WPS_KEYPAD) { - mView.findViewById(R.id.wps_pin_entry).setVisibility(View.VISIBLE); - } else { - mView.findViewById(R.id.wps_pin_entry).setVisibility(View.GONE); - } - return; - } - - @Override - public void onNothingSelected(AdapterView<?> parent) { - } - -} diff --git a/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java b/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java index 0747d64..cde44cd 100644 --- a/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java +++ b/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java @@ -27,18 +27,21 @@ import android.os.Message; import android.preference.CheckBoxPreference; import android.preference.Preference; import android.provider.Settings; +import android.widget.CompoundButton; +import android.widget.Switch; import android.util.Log; /** * WifiP2pEnabler is a helper to manage the Wifi p2p on/off */ -public class WifiP2pEnabler implements Preference.OnPreferenceChangeListener { +public class WifiP2pEnabler implements CompoundButton.OnCheckedChangeListener { private static final String TAG = "WifiP2pEnabler"; private final Context mContext; - private final CheckBoxPreference mCheckBox; private final IntentFilter mIntentFilter; + private Switch mSwitch; private WifiP2pManager mWifiP2pManager; + private boolean mStateMachineEvent; private WifiP2pManager.Channel mChannel; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -53,9 +56,9 @@ public class WifiP2pEnabler implements Preference.OnPreferenceChangeListener { } }; - public WifiP2pEnabler(Context context, CheckBoxPreference checkBox) { + public WifiP2pEnabler(Context context, Switch switch_) { mContext = context; - mCheckBox = checkBox; + mSwitch = switch_; mWifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE); if (mWifiP2pManager != null) { @@ -64,7 +67,7 @@ public class WifiP2pEnabler implements Preference.OnPreferenceChangeListener { //Failure to set up connection Log.e(TAG, "Failed to set up connection with wifi p2p service"); mWifiP2pManager = null; - mCheckBox.setEnabled(false); + mSwitch.setEnabled(false); } } else { Log.e(TAG, "mWifiP2pManager is null!"); @@ -76,42 +79,54 @@ public class WifiP2pEnabler implements Preference.OnPreferenceChangeListener { public void resume() { if (mWifiP2pManager == null) return; mContext.registerReceiver(mReceiver, mIntentFilter); - mCheckBox.setOnPreferenceChangeListener(this); + mSwitch.setOnCheckedChangeListener(this); } public void pause() { if (mWifiP2pManager == null) return; mContext.unregisterReceiver(mReceiver); - mCheckBox.setOnPreferenceChangeListener(null); + mSwitch.setOnCheckedChangeListener(null); } - public boolean onPreferenceChange(Preference preference, Object value) { + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (mWifiP2pManager == null) return false; + if (mStateMachineEvent) return; - mCheckBox.setEnabled(false); - final boolean enable = (Boolean) value; - if (enable) { + if (mWifiP2pManager == null) return; + + mSwitch.setEnabled(false); + if (isChecked) { mWifiP2pManager.enableP2p(mChannel); } else { mWifiP2pManager.disableP2p(mChannel); } - return false; } private void handleP2pStateChanged(int state) { - mCheckBox.setEnabled(true); + setSwitchChecked(true); switch (state) { case WifiP2pManager.WIFI_P2P_STATE_ENABLED: - mCheckBox.setChecked(true); + setSwitchChecked(true); + mSwitch.setEnabled(true); break; case WifiP2pManager.WIFI_P2P_STATE_DISABLED: - mCheckBox.setChecked(false); + setSwitchChecked(false); + mSwitch.setEnabled(true); break; default: + mSwitch.setEnabled(false); + setSwitchChecked(false); Log.e(TAG,"Unhandled wifi state " + state); break; } } + private void setSwitchChecked(boolean checked) { + if (checked != mSwitch.isChecked()) { + mStateMachineEvent = true; + mSwitch.setChecked(checked); + mStateMachineEvent = false; + } + } + } diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java index f6588b9..cf3b303 100644 --- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java +++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java @@ -32,8 +32,10 @@ import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pManager; import android.net.wifi.p2p.WifiP2pManager.PeerListListener; +import android.net.wifi.WpsInfo; import android.os.Bundle; -import android.os.Message; +import android.os.Handler; +import android.os.SystemProperties; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceCategory; @@ -45,6 +47,8 @@ import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.widget.Switch; +import android.widget.Toast; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; @@ -60,25 +64,27 @@ public class WifiP2pSettings extends SettingsPreferenceFragment implements PeerListListener { private static final String TAG = "WifiP2pSettings"; + private static final boolean DBG = false; private static final int MENU_ID_SEARCH = Menu.FIRST; - private static final int MENU_ID_CREATE_GROUP = Menu.FIRST + 1; - private static final int MENU_ID_REMOVE_GROUP = Menu.FIRST + 2; - private static final int MENU_ID_ADVANCED = Menu.FIRST +3; - + private static final int MENU_ID_RENAME = Menu.FIRST + 1; private final IntentFilter mIntentFilter = new IntentFilter(); private WifiP2pManager mWifiP2pManager; private WifiP2pManager.Channel mChannel; - private WifiP2pDialog mConnectDialog; - private OnClickListener mConnectListener; private OnClickListener mDisconnectListener; private WifiP2pPeer mSelectedWifiPeer; + private WifiP2pEnabler mWifiP2pEnabler; + private boolean mWifiP2pEnabled; + private boolean mWifiP2pSearching; + private int mConnectedDevices; + + private Handler mUiHandler; + private PreferenceGroup mPeersGroup; private Preference mThisDevicePref; - private static final int DIALOG_CONNECT = 1; - private static final int DIALOG_DISCONNECT = 2; + private static final int DIALOG_DISCONNECT = 1; private WifiP2pDevice mThisDevice; private WifiP2pDeviceList mPeers = new WifiP2pDeviceList(); @@ -89,7 +95,9 @@ public class WifiP2pSettings extends SettingsPreferenceFragment String action = intent.getAction(); if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { - //TODO: nothing right now + mWifiP2pEnabled = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, + WifiP2pManager.WIFI_P2P_STATE_DISABLED) == WifiP2pManager.WIFI_P2P_STATE_ENABLED; + handleP2pStateChanged(); } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { if (mWifiP2pManager != null) { mWifiP2pManager.requestPeers(mChannel, WifiP2pSettings.this); @@ -99,12 +107,12 @@ public class WifiP2pSettings extends SettingsPreferenceFragment NetworkInfo networkInfo = (NetworkInfo) intent.getParcelableExtra( WifiP2pManager.EXTRA_NETWORK_INFO); if (networkInfo.isConnected()) { - Log.d(TAG, "Connected"); + if (DBG) Log.d(TAG, "Connected"); } } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { mThisDevice = (WifiP2pDevice) intent.getParcelableExtra( WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); - Log.d(TAG, "Update device info: " + mThisDevice); + if (DBG) Log.d(TAG, "Update device info: " + mThisDevice); updateDevicePref(); } } @@ -120,6 +128,8 @@ public class WifiP2pSettings extends SettingsPreferenceFragment mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); + mUiHandler = new Handler(); + final Activity activity = getActivity(); mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); if (mWifiP2pManager != null) { @@ -133,27 +143,6 @@ public class WifiP2pSettings extends SettingsPreferenceFragment Log.e(TAG, "mWifiP2pManager is null !"); } - //connect dialog listener - mConnectListener = new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - WifiP2pConfig config = mConnectDialog.getConfig(); - if (mWifiP2pManager != null) { - mWifiP2pManager.connect(mChannel, config, - new WifiP2pManager.ActionListener() { - public void onSuccess() { - Log.d(TAG, " connect success"); - } - public void onFailure(int reason) { - Log.d(TAG, " connect fail " + reason); - } - }); - } - } - } - }; - //disconnect dialog listener mDisconnectListener = new OnClickListener() { @Override @@ -162,96 +151,101 @@ public class WifiP2pSettings extends SettingsPreferenceFragment if (mWifiP2pManager != null) { mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() { public void onSuccess() { - Log.d(TAG, " remove group success"); + if (DBG) Log.d(TAG, " remove group success"); } public void onFailure(int reason) { - Log.d(TAG, " remove group fail " + reason); + if (DBG) Log.d(TAG, " remove group fail " + reason); } }); } } } }; + + Switch actionBarSwitch = new Switch(activity); + + if (activity instanceof PreferenceActivity) { + PreferenceActivity preferenceActivity = (PreferenceActivity) activity; + if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) { + final int padding = activity.getResources().getDimensionPixelSize( + R.dimen.action_bar_switch_padding); + actionBarSwitch.setPadding(0, 0, padding, 0); + activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, + ActionBar.DISPLAY_SHOW_CUSTOM); + activity.getActionBar().setCustomView(actionBarSwitch, new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, + ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.RIGHT)); + } + } + + mWifiP2pEnabler = new WifiP2pEnabler(activity, actionBarSwitch); + + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + preferenceScreen.removeAll(); + + preferenceScreen.setOrderingAsAdded(true); + mThisDevicePref = new Preference(getActivity()); + preferenceScreen.addPreference(mThisDevicePref); + setHasOptionsMenu(true); } @Override public void onResume() { super.onResume(); + mWifiP2pEnabler.resume(); getActivity().registerReceiver(mReceiver, mIntentFilter); - - if (mWifiP2pManager != null) { - mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { - public void onSuccess() { - Log.d(TAG, " discover success"); - } - public void onFailure(int reason) { - Log.d(TAG, " discover fail " + reason); - } - }); - } + startSearch(); } @Override public void onPause() { super.onPause(); + mWifiP2pEnabler.pause(); getActivity().unregisterReceiver(mReceiver); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - menu.add(Menu.NONE, MENU_ID_SEARCH, 0, R.string.wifi_p2p_menu_search) + int textId = mWifiP2pSearching ? R.string.wifi_p2p_menu_searching : + R.string.wifi_p2p_menu_search; + menu.add(Menu.NONE, MENU_ID_SEARCH, 0, textId) + .setEnabled(mWifiP2pEnabled) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - menu.add(Menu.NONE, MENU_ID_CREATE_GROUP, 0, R.string.wifi_p2p_menu_create_group) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - menu.add(Menu.NONE, MENU_ID_REMOVE_GROUP, 0, R.string.wifi_p2p_menu_remove_group) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_p2p_menu_advanced) + menu.add(Menu.NONE, MENU_ID_RENAME, 0, R.string.wifi_p2p_menu_rename) + .setEnabled(mWifiP2pEnabled) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); super.onCreateOptionsMenu(menu, inflater); } @Override + public void onPrepareOptionsMenu(Menu menu) { + MenuItem searchMenu = menu.findItem(MENU_ID_SEARCH); + MenuItem renameMenu = menu.findItem(MENU_ID_RENAME); + if (mWifiP2pEnabled) { + searchMenu.setEnabled(true); + renameMenu.setEnabled(true); + } else { + searchMenu.setEnabled(false); + renameMenu.setEnabled(false); + } + + if (mWifiP2pSearching) { + searchMenu.setTitle(R.string.wifi_p2p_menu_searching); + } else { + searchMenu.setTitle(R.string.wifi_p2p_menu_search); + } + } + + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_ID_SEARCH: - if (mWifiP2pManager != null) { - mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { - public void onSuccess() { - Log.d(TAG, " discover success"); - } - public void onFailure(int reason) { - Log.d(TAG, " discover fail " + reason); - } - }); - } - return true; - case MENU_ID_CREATE_GROUP: - if (mWifiP2pManager != null) { - mWifiP2pManager.createGroup(mChannel, new WifiP2pManager.ActionListener() { - public void onSuccess() { - Log.d(TAG, " create group success"); - } - public void onFailure(int reason) { - Log.d(TAG, " create group fail " + reason); - } - }); - } - return true; - case MENU_ID_REMOVE_GROUP: - if (mWifiP2pManager != null) { - mWifiP2pManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() { - public void onSuccess() { - Log.d(TAG, " remove group success"); - } - public void onFailure(int reason) { - Log.d(TAG, " remove group fail " + reason); - } - }); - } + startSearch(); return true; - case MENU_ID_ADVANCED: - //TODO: add advanced settings for p2p + case MENU_ID_RENAME: + //TODO: handle rename return true; } return super.onOptionsItemSelected(item); @@ -264,7 +258,35 @@ public class WifiP2pSettings extends SettingsPreferenceFragment if (mSelectedWifiPeer.device.status == WifiP2pDevice.CONNECTED) { showDialog(DIALOG_DISCONNECT); } else { - showDialog(DIALOG_CONNECT); + WifiP2pConfig config = new WifiP2pConfig(); + config.deviceAddress = mSelectedWifiPeer.device.deviceAddress; + + int forceWps = SystemProperties.getInt("wifidirect.wps", -1); + + if (forceWps != -1) { + config.wps.setup = forceWps; + } else { + if (mSelectedWifiPeer.device.wpsPbcSupported()) { + config.wps.setup = WpsInfo.PBC; + } else if (mSelectedWifiPeer.device.wpsKeypadSupported()) { + config.wps.setup = WpsInfo.KEYPAD; + } else { + config.wps.setup = WpsInfo.DISPLAY; + } + } + + mWifiP2pManager.connect(mChannel, config, + new WifiP2pManager.ActionListener() { + public void onSuccess() { + if (DBG) Log.d(TAG, " connect success"); + } + public void onFailure(int reason) { + Log.e(TAG, " connect fail " + reason); + Toast.makeText(getActivity(), + R.string.wifi_p2p_failed_connect_message, + Toast.LENGTH_SHORT).show(); + } + }); } } return super.onPreferenceTreeClick(screen, preference); @@ -272,14 +294,15 @@ public class WifiP2pSettings extends SettingsPreferenceFragment @Override public Dialog onCreateDialog(int id) { - if (id == DIALOG_CONNECT) { - mConnectDialog = new WifiP2pDialog(getActivity(), mConnectListener, - mSelectedWifiPeer.device); - return mConnectDialog; - } else if (id == DIALOG_DISCONNECT) { + if (id == DIALOG_DISCONNECT) { + int stringId = (mConnectedDevices > 1) ? R.string.wifi_p2p_disconnect_multiple_message : + R.string.wifi_p2p_disconnect_message; + String deviceName = TextUtils.isEmpty(mSelectedWifiPeer.device.deviceName) ? + mSelectedWifiPeer.device.deviceAddress : + mSelectedWifiPeer.device.deviceName; AlertDialog dialog = new AlertDialog.Builder(getActivity()) - .setTitle("Disconnect ?") - .setMessage("Do you want to disconnect ?") + .setTitle(R.string.wifi_p2p_disconnect_title) + .setMessage(getActivity().getString(stringId, deviceName)) .setPositiveButton(getActivity().getString(R.string.dlg_ok), mDisconnectListener) .setNegativeButton(getActivity().getString(R.string.dlg_cancel), null) .create(); @@ -289,33 +312,61 @@ public class WifiP2pSettings extends SettingsPreferenceFragment } public void onPeersAvailable(WifiP2pDeviceList peers) { + mPeersGroup.removeAll(); - final PreferenceScreen preferenceScreen = getPreferenceScreen(); - preferenceScreen.removeAll(); + mPeers = peers; + mConnectedDevices = 0; + for (WifiP2pDevice peer: peers.getDeviceList()) { + mPeersGroup.addPreference(new WifiP2pPeer(getActivity(), peer)); + if (peer.status == WifiP2pDevice.CONNECTED) mConnectedDevices++; + } + } - preferenceScreen.setOrderingAsAdded(true); + private void handleP2pStateChanged() { + updateSearchMenu(false); + if (mWifiP2pEnabled) { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + preferenceScreen.removeAll(); + + preferenceScreen.setOrderingAsAdded(true); + mThisDevicePref = new Preference(getActivity()); + preferenceScreen.addPreference(mThisDevicePref); - if (mPeersGroup == null) { mPeersGroup = new PreferenceCategory(getActivity()); - } else { - mPeersGroup.removeAll(); - } + mPeersGroup.setTitle(R.string.wifi_p2p_peer_devices); + mPeersGroup.setEnabled(true); + preferenceScreen.addPreference(mPeersGroup); - preferenceScreen.addPreference(mThisDevicePref); + startSearch(); + } + } - mPeersGroup.setTitle(R.string.wifi_p2p_available_devices); - mPeersGroup.setEnabled(true); - preferenceScreen.addPreference(mPeersGroup); + private void updateSearchMenu(boolean searching) { + mWifiP2pSearching = searching; + Activity activity = getActivity(); + if (activity != null) activity.invalidateOptionsMenu(); + } - mPeers = peers; - for (WifiP2pDevice peer: peers.getDeviceList()) { - mPeersGroup.addPreference(new WifiP2pPeer(getActivity(), peer)); + private void startSearch() { + if (mWifiP2pManager != null && !mWifiP2pSearching) { + mWifiP2pManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { + public void onSuccess() { + updateSearchMenu(true); + //Allow 20s to discover devices + mUiHandler.postDelayed(new Runnable() { + public void run() { + updateSearchMenu(false); + }}, 20000); + } + public void onFailure(int reason) { + if (DBG) Log.d(TAG, " discover fail " + reason); + updateSearchMenu(false); + } + }); } } private void updateDevicePref() { - mThisDevicePref = new Preference(getActivity()); - if (mThisDevice != null) { if (TextUtils.isEmpty(mThisDevice.deviceName)) { mThisDevicePref.setTitle(mThisDevice.deviceAddress); @@ -323,15 +374,9 @@ public class WifiP2pSettings extends SettingsPreferenceFragment mThisDevicePref.setTitle(mThisDevice.deviceName); } - if (mThisDevice.status == WifiP2pDevice.CONNECTED) { - String[] statusArray = getActivity().getResources().getStringArray( - R.array.wifi_p2p_status); - mThisDevicePref.setSummary(statusArray[mThisDevice.status]); - } mThisDevicePref.setPersistent(false); mThisDevicePref.setEnabled(true); mThisDevicePref.setSelectable(false); } - onPeersAvailable(mPeers); //update UI } } |