summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/settings/AccessibilitySettings.java44
-rw-r--r--src/com/android/settings/ApplicationSettings.java39
-rw-r--r--src/com/android/settings/ChooseLockGeneric.java46
-rw-r--r--src/com/android/settings/ChooseLockPassword.java6
-rw-r--r--src/com/android/settings/ChooseLockSettingsHelper.java8
-rw-r--r--src/com/android/settings/ConfirmLockPassword.java33
-rw-r--r--src/com/android/settings/ConfirmLockPattern.java7
-rw-r--r--src/com/android/settings/CredentialStorage.java492
-rw-r--r--src/com/android/settings/CryptKeeperSettings.java16
-rw-r--r--src/com/android/settings/DateTimeSettingsSetupWizard.java7
-rw-r--r--src/com/android/settings/DefaultRingtonePreference.java1
-rw-r--r--src/com/android/settings/DisplaySettings.java103
-rw-r--r--src/com/android/settings/DreamComponentPreference.java139
-rw-r--r--src/com/android/settings/DreamSettings.java128
-rw-r--r--src/com/android/settings/DreamTesterPreference.java75
-rw-r--r--src/com/android/settings/RadioInfo.java24
-rw-r--r--src/com/android/settings/SecuritySettings.java17
-rw-r--r--src/com/android/settings/Settings.java9
-rw-r--r--src/com/android/settings/SettingsCheckBoxPreference.java91
-rw-r--r--src/com/android/settings/SettingsLicenseActivity.java3
-rw-r--r--src/com/android/settings/SubSettings.java24
-rw-r--r--src/com/android/settings/TestingSettingsBroadcastReceiver.java1
-rw-r--r--src/com/android/settings/TextToSpeechSettings.java548
-rw-r--r--src/com/android/settings/UserDictionarySettings.java94
-rw-r--r--src/com/android/settings/Utils.java22
-rw-r--r--src/com/android/settings/accounts/AccountPreferenceBase.java14
-rw-r--r--src/com/android/settings/accounts/ChooseAccountActivity.java10
-rw-r--r--src/com/android/settings/deviceinfo/PercentageBarChart.java19
-rw-r--r--src/com/android/settings/deviceinfo/StorageMeasurement.java1
-rw-r--r--src/com/android/settings/deviceinfo/UsageBarPreference.java6
-rw-r--r--src/com/android/settings/fuelgauge/BatteryHistoryChart.java17
-rw-r--r--src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java30
-rw-r--r--src/com/android/settings/inputmethod/UserDictionaryList.java109
-rw-r--r--src/com/android/settings/vpn/VpnSettings.java7
-rw-r--r--src/com/android/settings/wifi/WifiSettings.java4
-rw-r--r--src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java47
36 files changed, 1621 insertions, 620 deletions
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index 826410d..9a0db5d 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -16,6 +16,7 @@
package com.android.settings;
+import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Service;
@@ -78,7 +79,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private CheckBoxPreference mToggleAccessibilityCheckBox;
private CheckBoxPreference mToggleScriptInjectionCheckBox;
- private CheckBoxPreference mToggleAccessibilityServiceCheckBox;
+ private SettingsCheckBoxPreference mToggleAccessibilityServiceCheckBox;
private PreferenceCategory mPowerButtonCategory;
private CheckBoxPreference mPowerButtonEndsCallCheckBox;
@@ -87,8 +88,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private ListPreference mLongPressTimeoutListPreference;
- private Map<String, ServiceInfo> mAccessibilityServices =
- new LinkedHashMap<String, ServiceInfo>();
+ private Map<String, AccessibilityServiceInfo> mAccessibilityServices =
+ new LinkedHashMap<String, AccessibilityServiceInfo>();
private TextUtils.SimpleStringSplitter mStringColonSplitter =
new TextUtils.SimpleStringSplitter(':');
@@ -157,7 +158,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
}
}
- Map<String, ServiceInfo> accessibilityServices = mAccessibilityServices;
+ Map<String, AccessibilityServiceInfo> accessibilityServices = mAccessibilityServices;
for (String key : accessibilityServices.keySet()) {
CheckBoxPreference preference = (CheckBoxPreference) findPreference(key);
@@ -230,9 +231,9 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
throw new IllegalArgumentException(
KEY_TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX
+ " must be mapped to an instance of a "
- + CheckBoxPreference.class.getName());
+ + SettingsCheckBoxPreference.class.getName());
}
- mToggleAccessibilityServiceCheckBox = (CheckBoxPreference) preference;
+ mToggleAccessibilityServiceCheckBox = (SettingsCheckBoxPreference) preference;
}
}
@@ -274,7 +275,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} else if (TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX.equals(key)) {
handleToggleAccessibilityScriptInjection((CheckBoxPreference) preference);
} else if (preference instanceof CheckBoxPreference) {
- handleEnableAccessibilityServiceStateChange((CheckBoxPreference) preference);
+ handleEnableAccessibilityServiceStateChange((SettingsCheckBoxPreference) preference);
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
@@ -318,7 +319,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
*
* @param preference The preference.
*/
- private void handleEnableAccessibilityServiceStateChange(CheckBoxPreference preference) {
+ private void handleEnableAccessibilityServiceStateChange(
+ SettingsCheckBoxPreference preference) {
if (preference.isChecked()) {
mToggleAccessibilityServiceCheckBox = preference;
// set right enabled state since the user may press back
@@ -357,7 +359,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
AccessibilityManager accessibilityManager =
(AccessibilityManager) getSystemService(Service.ACCESSIBILITY_SERVICE);
- List<ServiceInfo> installedServices = accessibilityManager.getAccessibilityServiceList();
+ List<AccessibilityServiceInfo> installedServices =
+ accessibilityManager.getInstalledAccessibilityServiceList();
if (installedServices.isEmpty()) {
getPreferenceScreen().removePreference(mAccessibilityServicesCategory);
@@ -367,12 +370,22 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
getPreferenceScreen().addPreference(mAccessibilityServicesCategory);
for (int i = 0, count = installedServices.size(); i < count; ++i) {
- ServiceInfo serviceInfo = installedServices.get(i);
- String key = serviceInfo.packageName + "/" + serviceInfo.name;
-
- if (mAccessibilityServices.put(key, serviceInfo) == null) {
- CheckBoxPreference preference = new CheckBoxPreference(getActivity());
+ AccessibilityServiceInfo accessibilityServiceInfo = installedServices.get(i);
+ String key = accessibilityServiceInfo.getId();
+
+ if (mAccessibilityServices.put(key, accessibilityServiceInfo) == null) {
+ String settingsActivityName = accessibilityServiceInfo.getSettingsActivityName();
+ Intent settingsIntent = null;
+ if (!TextUtils.isEmpty(settingsActivityName)) {
+ String packageName = accessibilityServiceInfo.getResolveInfo()
+ .serviceInfo.packageName;
+ settingsIntent = new Intent(Intent.ACTION_MAIN);
+ settingsIntent.setClassName(packageName, settingsActivityName);
+ }
+ SettingsCheckBoxPreference preference = new SettingsCheckBoxPreference(
+ getActivity(), settingsIntent);
preference.setKey(key);
+ ServiceInfo serviceInfo = accessibilityServiceInfo.getResolveInfo().serviceInfo;
preference.setTitle(serviceInfo.loadLabel(getActivity().getPackageManager()));
mAccessibilityServicesCategory.addPreference(preference);
}
@@ -424,7 +437,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
.setMessage(getResources().getString(
R.string.accessibility_service_security_warning,
mAccessibilityServices.get(mToggleAccessibilityServiceCheckBox.getKey())
- .applicationInfo.loadLabel(getActivity().getPackageManager())))
+ .getResolveInfo().serviceInfo.applicationInfo.loadLabel(
+ getActivity().getPackageManager())))
.setCancelable(true)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
diff --git a/src/com/android/settings/ApplicationSettings.java b/src/com/android/settings/ApplicationSettings.java
index da417ec..bb0f66f 100644
--- a/src/com/android/settings/ApplicationSettings.java
+++ b/src/com/android/settings/ApplicationSettings.java
@@ -18,6 +18,7 @@ package com.android.settings;
import android.app.AlertDialog;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
@@ -26,11 +27,13 @@ import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings;
+import android.util.Log;
public class ApplicationSettings extends SettingsPreferenceFragment implements
DialogInterface.OnClickListener {
private static final String KEY_TOGGLE_INSTALL_APPLICATIONS = "toggle_install_applications";
+ private static final String KEY_TOGGLE_ADVANCED_SETTINGS = "toggle_advanced_settings";
private static final String KEY_APP_INSTALL_LOCATION = "app_install_location";
// App installation location. Default is ask the user.
@@ -43,9 +46,8 @@ public class ApplicationSettings extends SettingsPreferenceFragment implements
private static final String APP_INSTALL_AUTO_ID = "auto";
private CheckBoxPreference mToggleAppInstallation;
-
+ private CheckBoxPreference mToggleAdvancedSettings;
private ListPreference mInstallLocation;
-
private DialogInterface mWarnInstallApps;
@Override
@@ -54,9 +56,19 @@ public class ApplicationSettings extends SettingsPreferenceFragment implements
addPreferencesFromResource(R.xml.application_settings);
- mToggleAppInstallation = (CheckBoxPreference) findPreference(KEY_TOGGLE_INSTALL_APPLICATIONS);
+ mToggleAppInstallation = (CheckBoxPreference)findPreference(
+ KEY_TOGGLE_INSTALL_APPLICATIONS);
mToggleAppInstallation.setChecked(isNonMarketAppsAllowed());
+ mToggleAdvancedSettings = (CheckBoxPreference)findPreference(
+ KEY_TOGGLE_ADVANCED_SETTINGS);
+ mToggleAdvancedSettings.setChecked(isAdvancedSettingsEnabled());
+
+ // not ready for prime time yet
+ if (false) {
+ getPreferenceScreen().removePreference(mInstallLocation);
+ }
+
mInstallLocation = (ListPreference) findPreference(KEY_APP_INSTALL_LOCATION);
// Is app default install location set?
boolean userSetInstLocation = (Settings.System.getInt(getContentResolver(),
@@ -110,6 +122,9 @@ public class ApplicationSettings extends SettingsPreferenceFragment implements
} else {
setNonMarketAppsAllowed(false);
}
+ } else if (preference == mToggleAdvancedSettings) {
+ boolean value = mToggleAdvancedSettings.isChecked();
+ setAdvancedSettingsEnabled(value);
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
@@ -127,7 +142,23 @@ public class ApplicationSettings extends SettingsPreferenceFragment implements
Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS,
enabled ? 1 : 0);
}
-
+
+ private boolean isAdvancedSettingsEnabled() {
+ return Settings.System.getInt(getContentResolver(),
+ Settings.System.ADVANCED_SETTINGS,
+ Settings.System.ADVANCED_SETTINGS_DEFAULT) > 0;
+ }
+
+ private void setAdvancedSettingsEnabled(boolean enabled) {
+ int value = enabled ? 1 : 0;
+ // Change the system setting
+ Settings.Secure.putInt(getContentResolver(), Settings.System.ADVANCED_SETTINGS, value);
+ // TODO: the settings thing should broadcast this for thread safety purposes.
+ Intent intent = new Intent(Intent.ACTION_ADVANCED_SETTINGS_CHANGED);
+ intent.putExtra("state", value);
+ getActivity().sendBroadcast(intent);
+ }
+
private boolean isNonMarketAppsAllowed() {
return Settings.Secure.getInt(getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 0) > 0;
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 118bc6f..8311c4a 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -27,6 +27,7 @@ import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
+import android.security.KeyStore;
public class ChooseLockGeneric extends PreferenceActivity {
@@ -48,9 +49,11 @@ public class ChooseLockGeneric extends PreferenceActivity {
private static final int CONFIRM_EXISTING_REQUEST = 100;
private static final String PASSWORD_CONFIRMED = "password_confirmed";
private static final String CONFIRM_CREDENTIALS = "confirm_credentials";
+ public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
private DevicePolicyManager mDPM;
+ private KeyStore mKeyStore;
private boolean mPasswordConfirmed = false;
@Override
@@ -58,6 +61,7 @@ public class ChooseLockGeneric extends PreferenceActivity {
super.onCreate(savedInstanceState);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+ mKeyStore = KeyStore.getInstance();
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
if (savedInstanceState != null) {
@@ -126,8 +130,8 @@ public class ChooseLockGeneric extends PreferenceActivity {
.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
if (quality == -1) {
// If caller didn't specify password quality, show UI and allow the user to choose.
- quality = mDPM.getPasswordQuality(null);
- quality = upgradeQualityForEncryption(quality);
+ quality = getActivity().getIntent().getIntExtra(MINIMUM_QUALITY_KEY, -1);
+ quality = upgradeQuality(quality);
final PreferenceScreen prefScreen = getPreferenceScreen();
if (prefScreen != null) {
prefScreen.removeAll();
@@ -135,11 +139,26 @@ public class ChooseLockGeneric extends PreferenceActivity {
addPreferencesFromResource(R.xml.security_settings_picker);
disableUnusablePreferences(quality);
} else {
- quality = upgradeQualityForEncryption(quality);
updateUnlockMethodAndFinish(quality, false);
}
}
+ private int upgradeQuality(int quality) {
+ quality = upgradeQualityForDPM(quality);
+ quality = upgradeQualityForEncryption(quality);
+ quality = upgradeQualityForKeyStore(quality);
+ return quality;
+ }
+
+ private int upgradeQualityForDPM(int quality) {
+ // Compare min allowed password quality
+ int minQuality = mDPM.getPasswordQuality(null);
+ if (quality < minQuality) {
+ quality = minQuality;
+ }
+ return quality;
+ }
+
/**
* Mix in "encryption minimums" to any given quality value. This prevents users
* from downgrading the pattern/pin/password to a level below the minimums.
@@ -152,8 +171,17 @@ public class ChooseLockGeneric extends PreferenceActivity {
boolean encrypted = (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE)
|| (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING);
if (encrypted) {
- if (quality < DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
- quality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+ if (quality < CryptKeeperSettings.MIN_PASSWORD_QUALITY) {
+ quality = CryptKeeperSettings.MIN_PASSWORD_QUALITY;
+ }
+ }
+ return quality;
+ }
+
+ private int upgradeQualityForKeyStore(int quality) {
+ if (!mKeyStore.isEmpty()) {
+ if (quality < CredentialStorage.MIN_PASSWORD_QUALITY) {
+ quality = CredentialStorage.MIN_PASSWORD_QUALITY;
}
}
return quality;
@@ -208,13 +236,7 @@ public class ChooseLockGeneric extends PreferenceActivity {
throw new IllegalStateException("Tried to update password without confirming it");
}
- // Compare min allowed password quality and launch appropriate security setting method
- int minQuality = mDPM.getPasswordQuality(null);
- if (quality < minQuality) {
- quality = minQuality;
- }
- quality = upgradeQualityForEncryption(quality);
-
+ quality = upgradeQuality(quality);
if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
int minLength = mDPM.getPasswordMinimumLength(null);
if (minLength < MIN_PASSWORD_LENGTH) {
diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java
index a0f2346..96255eb 100644
--- a/src/com/android/settings/ChooseLockPassword.java
+++ b/src/com/android/settings/ChooseLockPassword.java
@@ -405,8 +405,10 @@ public class ChooseLockPassword extends PreferenceActivity {
}
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- // Check if this was the result of hitting the enter key
- if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN) {
+ // Check if this was the result of hitting the enter or "done" key
+ if (actionId == EditorInfo.IME_NULL
+ || actionId == EditorInfo.IME_ACTION_DONE
+ || actionId == EditorInfo.IME_ACTION_NEXT) {
handleNext();
return true;
}
diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java
index d31fe3b..a069712 100644
--- a/src/com/android/settings/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/ChooseLockSettingsHelper.java
@@ -23,7 +23,10 @@ import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
-public class ChooseLockSettingsHelper {
+public final class ChooseLockSettingsHelper {
+
+ static final String EXTRA_KEY_PASSWORD = "password";
+
private LockPatternUtils mLockPatternUtils;
private Activity mActivity;
private Fragment mFragment;
@@ -49,8 +52,7 @@ public class ChooseLockSettingsHelper {
* @return true if one exists and we launched an activity to confirm it
* @see #onActivityResult(int, int, android.content.Intent)
*/
- protected boolean launchConfirmationActivity(int request,
- CharSequence message, CharSequence details) {
+ boolean launchConfirmationActivity(int request, CharSequence message, CharSequence details) {
boolean launched = false;
switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index 3f4a4f3..1229046 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -27,13 +27,16 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceActivity;
+import android.text.Editable;
import android.text.InputType;
+import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -58,7 +61,7 @@ public class ConfirmLockPassword extends PreferenceActivity {
}
public static class ConfirmLockPasswordFragment extends Fragment implements OnClickListener,
- OnEditorActionListener {
+ OnEditorActionListener, TextWatcher {
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
private TextView mPasswordEntry;
private LockPatternUtils mLockPatternUtils;
@@ -66,6 +69,7 @@ public class ConfirmLockPassword extends PreferenceActivity {
private Handler mHandler = new Handler();
private PasswordEntryKeyboardHelper mKeyboardHelper;
private PasswordEntryKeyboardView mKeyboardView;
+ private Button mContinueButton;
// required constructor for fragments
@@ -87,9 +91,14 @@ public class ConfirmLockPassword extends PreferenceActivity {
// Disable IME on our window since we provide our own keyboard
view.findViewById(R.id.cancel_button).setOnClickListener(this);
- view.findViewById(R.id.next_button).setOnClickListener(this);
+ mContinueButton = (Button) view.findViewById(R.id.next_button);
+ mContinueButton.setOnClickListener(this);
+ mContinueButton.setEnabled(false); // disable until the user enters at least one char
+
mPasswordEntry = (TextView) view.findViewById(R.id.password_entry);
mPasswordEntry.setOnEditorActionListener(this);
+ mPasswordEntry.addTextChangedListener(this);
+
mKeyboardView = (PasswordEntryKeyboardView) view.findViewById(R.id.keyboard);
mHeaderText = (TextView) view.findViewById(R.id.headerText);
final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == storedQuality
@@ -140,7 +149,7 @@ public class ConfirmLockPassword extends PreferenceActivity {
if (mLockPatternUtils.checkPassword(pin)) {
Intent intent = new Intent();
- intent.putExtra("password", pin);
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pin);
getActivity().setResult(RESULT_OK, intent);
getActivity().finish();
@@ -172,13 +181,27 @@ public class ConfirmLockPassword extends PreferenceActivity {
}, ERROR_MESSAGE_TIMEOUT);
}
+ // {@link OnEditorActionListener} methods.
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- // Check if this was the result of hitting the enter key
- if (actionId == EditorInfo.IME_NULL) {
+ // Check if this was the result of hitting the enter or "done" key
+ if (actionId == EditorInfo.IME_NULL
+ || actionId == EditorInfo.IME_ACTION_DONE
+ || actionId == EditorInfo.IME_ACTION_NEXT) {
handleNext();
return true;
}
return false;
}
+
+ // {@link TextWatcher} methods.
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ public void afterTextChanged(Editable s) {
+ mContinueButton.setEnabled(mPasswordEntry.getText().length() > 0);
+ }
}
}
diff --git a/src/com/android/settings/ConfirmLockPattern.java b/src/com/android/settings/ConfirmLockPattern.java
index 0653d3f..2892930 100644
--- a/src/com/android/settings/ConfirmLockPattern.java
+++ b/src/com/android/settings/ConfirmLockPattern.java
@@ -256,7 +256,12 @@ public class ConfirmLockPattern extends PreferenceActivity {
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
if (mLockPatternUtils.checkPattern(pattern)) {
- getActivity().setResult(Activity.RESULT_OK);
+
+ Intent intent = new Intent();
+ intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD,
+ LockPatternUtils.patternToString(pattern));
+
+ getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();
} else {
if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL &&
diff --git a/src/com/android/settings/CredentialStorage.java b/src/com/android/settings/CredentialStorage.java
index 9d5a603..e246fce 100644
--- a/src/com/android/settings/CredentialStorage.java
+++ b/src/com/android/settings/CredentialStorage.java
@@ -18,213 +18,417 @@ package com.android.settings;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.res.Resources;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.RemoteException;
+import android.security.KeyChain.KeyChainConnection;
+import android.security.KeyChain;
import android.security.KeyStore;
import android.text.Editable;
+import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
+import com.android.internal.widget.LockPatternUtils;
-import java.io.UnsupportedEncodingException;
+/**
+ * CredentialStorage handles KeyStore reset, unlock, and install.
+ *
+ * CredentialStorage has a pretty convoluted state machine to migrate
+ * from the old style separate keystore password to a new key guard
+ * based password, as well as to deal with setting up the key guard if
+ * necessary.
+ *
+ * KeyStore: UNINITALIZED
+ * KeyGuard: OFF
+ * Action: set up key guard
+ * Notes: factory state
+ *
+ * KeyStore: UNINITALIZED
+ * KeyGuard: ON
+ * Action: confirm key guard
+ * Notes: user had key guard but no keystore and upgraded from pre-ICS
+ * OR user had key guard and pre-ICS keystore password which was then reset
+ *
+ * KeyStore: LOCKED
+ * KeyGuard: OFF/ON
+ * Action: old unlock dialog
+ * Notes: assume old password, need to use it to unlock.
+ * if unlock, ensure key guard before install.
+ * if reset, treat as UNINITALIZED/OFF
+ *
+ * KeyStore: UNLOCKED
+ * KeyGuard: OFF
+ * Action: set up key guard
+ * Notes: ensure key guard, then proceed
+ *
+ * KeyStore: UNLOCKED
+ * keyguard: ON
+ * Action: normal unlock/install
+ * Notes: this is the common case
+ */
+public final class CredentialStorage extends Activity {
-public class CredentialStorage extends Activity implements TextWatcher,
- DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+ private static final String TAG = "CredentialStorage";
public static final String ACTION_UNLOCK = "com.android.credentials.UNLOCK";
- public static final String ACTION_SET_PASSWORD = "com.android.credentials.SET_PASSWORD";
public static final String ACTION_INSTALL = "com.android.credentials.INSTALL";
public static final String ACTION_RESET = "com.android.credentials.RESET";
- private static final String TAG = "CredentialStorage";
+ // This is the minimum acceptable password quality. If the current password quality is
+ // lower than this, keystore should not be activated.
+ static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
- private KeyStore mKeyStore = KeyStore.getInstance();
- private boolean mSubmit = false;
- private Bundle mBundle;
+ private static final int CONFIRM_KEY_GUARD_REQUEST = 1;
- private TextView mOldPassword;
- private TextView mNewPassword;
- private TextView mConfirmPassword;
- private TextView mError;
- private Button mButton;
+ private final KeyStore mKeyStore = KeyStore.getInstance();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ /**
+ * When non-null, the bundle containing credentials to install.
+ */
+ private Bundle mInstallBundle;
+
+ /**
+ * After unsuccessful KeyStore.unlock, the number of unlock
+ * attempts remaining before the KeyStore will reset itself.
+ *
+ * Reset to -1 on successful unlock or reset.
+ */
+ private int mRetriesRemaining = -1;
+
+ @Override protected void onResume() {
+ super.onResume();
Intent intent = getIntent();
String action = intent.getAction();
- int state = mKeyStore.test();
if (ACTION_RESET.equals(action)) {
- showResetDialog();
- } else if (ACTION_SET_PASSWORD.equals(action)) {
- showPasswordDialog(state == KeyStore.UNINITIALIZED);
+ new ResetDialog();
} else {
if (ACTION_INSTALL.equals(action) &&
"com.android.certinstaller".equals(getCallingPackage())) {
- mBundle = intent.getExtras();
- }
- if (state == KeyStore.UNINITIALIZED) {
- showPasswordDialog(true);
- } else if (state == KeyStore.LOCKED) {
- showUnlockDialog();
- } else {
- install();
- finish();
+ mInstallBundle = intent.getExtras();
}
+ // ACTION_UNLOCK also handled here in addition to ACTION_INSTALL
+ handleUnlockOrInstall();
}
}
- private void install() {
- if (mBundle != null && !mBundle.isEmpty()) {
- try {
- for (String key : mBundle.keySet()) {
- byte[] value = mBundle.getByteArray(key);
- if (value != null && !mKeyStore.put(key.getBytes("UTF-8"), value)) {
- Log.e(TAG, "Failed to install " + key);
- return;
- }
+ /**
+ * Based on the current state of the KeyStore and key guard, try to
+ * make progress on unlocking or installing to the keystore.
+ */
+ private void handleUnlockOrInstall() {
+ // something already decided we are done, do not proceed
+ if (isFinishing()) {
+ return;
+ }
+ switch (mKeyStore.state()) {
+ case UNINITIALIZED: {
+ ensureKeyGuard();
+ return;
+ }
+ case LOCKED: {
+ new UnlockDialog();
+ return;
+ }
+ case UNLOCKED: {
+ if (!checkKeyGuardQuality()) {
+ new ConfigureKeyGuardDialog();
+ return;
}
- setResult(RESULT_OK);
- } catch (UnsupportedEncodingException e) {
- // Should never happen.
- throw new RuntimeException(e);
+ installIfAvailable();
+ finish();
+ return;
}
}
}
- private void showResetDialog() {
- AlertDialog dialog = new AlertDialog.Builder(this)
- .setTitle(android.R.string.dialog_alert_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setMessage(R.string.credentials_reset_hint)
- .setNeutralButton(android.R.string.ok, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
- dialog.setOnDismissListener(this);
- dialog.show();
+ /**
+ * Make sure the user enters the key guard to set or change the
+ * keystore password. This can be used in UNINITIALIZED to set the
+ * keystore password or UNLOCKED to change the password (as is the
+ * case after unlocking with an old-style password).
+ */
+ private void ensureKeyGuard() {
+ if (!checkKeyGuardQuality()) {
+ // key guard not setup, doing so will initialize keystore
+ new ConfigureKeyGuardDialog();
+ // will return to onResume after Activity
+ return;
+ }
+ // force key guard confirmation
+ if (confirmKeyGuard()) {
+ // will return password value via onActivityResult
+ return;
+ }
+ finish();
}
- private void showPasswordDialog(boolean firstTime) {
- View view = View.inflate(this, R.layout.credentials_dialog, null);
+ /**
+ * Returns true if the currently set key guard matches our minimum quality requirements.
+ */
+ private boolean checkKeyGuardQuality() {
+ int quality = new LockPatternUtils(this).getActivePasswordQuality();
+ return (quality >= MIN_PASSWORD_QUALITY);
+ }
- ((TextView) view.findViewById(R.id.hint)).setText(R.string.credentials_password_hint);
- if (!firstTime) {
- view.findViewById(R.id.old_password_prompt).setVisibility(View.VISIBLE);
- mOldPassword = (TextView) view.findViewById(R.id.old_password);
- mOldPassword.setVisibility(View.VISIBLE);
- mOldPassword.addTextChangedListener(this);
+ /**
+ * Install credentials if available, otherwise do nothing.
+ */
+ private void installIfAvailable() {
+ if (mInstallBundle != null && !mInstallBundle.isEmpty()) {
+ Bundle bundle = mInstallBundle;
+ mInstallBundle = null;
+ for (String key : bundle.keySet()) {
+ byte[] value = bundle.getByteArray(key);
+ if (value != null && !mKeyStore.put(key, value)) {
+ Log.e(TAG, "Failed to install " + key);
+ return;
+ }
+ }
+ setResult(RESULT_OK);
}
- view.findViewById(R.id.new_passwords).setVisibility(View.VISIBLE);
- mNewPassword = (TextView) view.findViewById(R.id.new_password);
- mNewPassword.addTextChangedListener(this);
- mConfirmPassword = (TextView) view.findViewById(R.id.confirm_password);
- mConfirmPassword.addTextChangedListener(this);
- mError = (TextView) view.findViewById(R.id.error);
-
- AlertDialog dialog = new AlertDialog.Builder(this)
- .setView(view)
- .setTitle(R.string.credentials_set_password)
- .setPositiveButton(android.R.string.ok, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
- dialog.setOnDismissListener(this);
- dialog.show();
- mButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
- mButton.setEnabled(false);
}
- private void showUnlockDialog() {
- View view = View.inflate(this, R.layout.credentials_dialog, null);
-
- ((TextView) view.findViewById(R.id.hint)).setText(R.string.credentials_unlock_hint);
- mOldPassword = (TextView) view.findViewById(R.id.old_password);
- mOldPassword.setVisibility(View.VISIBLE);
- mOldPassword.addTextChangedListener(this);
- mError = (TextView) view.findViewById(R.id.error);
-
- AlertDialog dialog = new AlertDialog.Builder(this)
- .setView(view)
- .setTitle(R.string.credentials_unlock)
- .setPositiveButton(android.R.string.ok, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
- dialog.setOnDismissListener(this);
- dialog.show();
- mButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
- mButton.setEnabled(false);
- }
+ /**
+ * Prompt for reset confirmation, resetting on confirmation, finishing otherwise.
+ */
+ private class ResetDialog
+ implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
+ {
+ private boolean mResetConfirmed;
- public void afterTextChanged(Editable editable) {
- if ((mOldPassword == null || mOldPassword.getText().length() > 0) &&
- (mNewPassword == null || mNewPassword.getText().length() >= 8) &&
- (mConfirmPassword == null || mConfirmPassword.getText().length() >= 8)) {
- mButton.setEnabled(true);
- } else {
- mButton.setEnabled(false);
+ private ResetDialog() {
+ AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this)
+ .setTitle(android.R.string.dialog_alert_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(R.string.credentials_reset_hint)
+ .setPositiveButton(android.R.string.ok, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
+ dialog.setOnDismissListener(this);
+ dialog.show();
}
- }
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
+ @Override public void onClick(DialogInterface dialog, int button) {
+ mResetConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
+ }
- public void onTextChanged(CharSequence s,int start, int before, int count) {
+ @Override public void onDismiss(DialogInterface dialog) {
+ if (mResetConfirmed) {
+ mResetConfirmed = false;
+ new ResetKeyStoreAndKeyChain().execute();
+ return;
+ }
+ finish();
+ }
}
- public void onClick(DialogInterface dialog, int button) {
- mSubmit = (button == DialogInterface.BUTTON_POSITIVE);
- if (button == DialogInterface.BUTTON_NEUTRAL) {
+ /**
+ * Background task to handle reset of both keystore and user installed CAs.
+ */
+ private class ResetKeyStoreAndKeyChain extends AsyncTask<Void, Void, Boolean> {
+
+ @Override protected Boolean doInBackground(Void... unused) {
+
mKeyStore.reset();
- Toast.makeText(this, R.string.credentials_erased, Toast.LENGTH_SHORT).show();
+
+ try {
+ KeyChainConnection keyChainConnection = KeyChain.bind(CredentialStorage.this);
+ try {
+ return keyChainConnection.getService().reset();
+ } catch (RemoteException e) {
+ return false;
+ } finally {
+ keyChainConnection.close();
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return false;
+ }
+ }
+
+ @Override protected void onPostExecute(Boolean success) {
+ if (success) {
+ Toast.makeText(CredentialStorage.this,
+ R.string.credentials_erased, Toast.LENGTH_SHORT).show();
+ } else {
+ Toast.makeText(CredentialStorage.this,
+ R.string.credentials_not_erased, Toast.LENGTH_SHORT).show();
+ }
+ finish();
}
}
- public void onDismiss(DialogInterface dialog) {
- if (mSubmit) {
- mSubmit = false;
- mError.setVisibility(View.VISIBLE);
+ /**
+ * Prompt for key guard configuration confirmation.
+ */
+ private class ConfigureKeyGuardDialog
+ implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
+ {
+ private boolean mConfigureConfirmed;
- if (mNewPassword == null) {
- mKeyStore.unlock(mOldPassword.getText().toString());
- } else {
- String newPassword = mNewPassword.getText().toString();
- String confirmPassword = mConfirmPassword.getText().toString();
+ private ConfigureKeyGuardDialog() {
+ AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this)
+ .setTitle(android.R.string.dialog_alert_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(R.string.credentials_configure_lock_screen_hint)
+ .setPositiveButton(android.R.string.ok, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
+ dialog.setOnDismissListener(this);
+ dialog.show();
+ }
+
+ @Override public void onClick(DialogInterface dialog, int button) {
+ mConfigureConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
+ }
- if (!newPassword.equals(confirmPassword)) {
- mError.setText(R.string.credentials_passwords_mismatch);
- ((AlertDialog) dialog).show();
+ @Override public void onDismiss(DialogInterface dialog) {
+ if (mConfigureConfirmed) {
+ mConfigureConfirmed = false;
+ Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
+ intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
+ MIN_PASSWORD_QUALITY);
+ startActivity(intent);
+ return;
+ }
+ finish();
+ }
+ }
+
+ /**
+ * Confirm existing key guard, returning password via onActivityResult.
+ */
+ private boolean confirmKeyGuard() {
+ Resources res = getResources();
+ boolean launched = new ChooseLockSettingsHelper(this)
+ .launchConfirmationActivity(CONFIRM_KEY_GUARD_REQUEST,
+ res.getText(R.string.master_clear_gesture_prompt),
+ res.getText(R.string.master_clear_gesture_explanation));
+ return launched;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ /**
+ * Receive key guard password initiated by confirmKeyGuard.
+ */
+ if (requestCode == CONFIRM_KEY_GUARD_REQUEST) {
+ if (resultCode == Activity.RESULT_OK) {
+ String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
+ if (!TextUtils.isEmpty(password)) {
+ // success
+ mKeyStore.password(password);
+ // return to onResume
return;
- } else if (mOldPassword == null) {
- mKeyStore.password(newPassword);
- } else {
- mKeyStore.password(mOldPassword.getText().toString(), newPassword);
}
}
+ // failed confirmation, bail
+ finish();
+ }
+ }
+
+ /**
+ * Prompt for unlock with old-style password.
+ *
+ * On successful unlock, ensure migration to key guard before continuing.
+ * On unsuccessful unlock, retry by calling handleUnlockOrInstall.
+ */
+ private class UnlockDialog implements TextWatcher,
+ DialogInterface.OnClickListener, DialogInterface.OnDismissListener
+ {
+ private boolean mUnlockConfirmed;
+
+ private final Button mButton;
+ private final TextView mOldPassword;
+ private final TextView mError;
+
+ private UnlockDialog() {
+ View view = View.inflate(CredentialStorage.this, R.layout.credentials_dialog, null);
+
+ CharSequence text;
+ if (mRetriesRemaining == -1) {
+ text = getResources().getText(R.string.credentials_unlock_hint);
+ } else if (mRetriesRemaining > 3) {
+ text = getResources().getText(R.string.credentials_wrong_password);
+ } else if (mRetriesRemaining == 1) {
+ text = getResources().getText(R.string.credentials_reset_warning);
+ } else {
+ text = getString(R.string.credentials_reset_warning_plural, mRetriesRemaining);
+ }
- int error = mKeyStore.getLastError();
- if (error == KeyStore.NO_ERROR) {
- Toast.makeText(this, R.string.credentials_enabled, Toast.LENGTH_SHORT).show();
- install();
- } else if (error == KeyStore.UNINITIALIZED) {
- Toast.makeText(this, R.string.credentials_erased, Toast.LENGTH_SHORT).show();
- } else if (error >= KeyStore.WRONG_PASSWORD) {
- int count = error - KeyStore.WRONG_PASSWORD + 1;
- if (count > 3) {
- mError.setText(R.string.credentials_wrong_password);
- } else if (count == 1) {
- mError.setText(R.string.credentials_reset_warning);
- } else {
- mError.setText(getString(R.string.credentials_reset_warning_plural, count));
+ ((TextView) view.findViewById(R.id.hint)).setText(text);
+ mOldPassword = (TextView) view.findViewById(R.id.old_password);
+ mOldPassword.setVisibility(View.VISIBLE);
+ mOldPassword.addTextChangedListener(this);
+ mError = (TextView) view.findViewById(R.id.error);
+
+ AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this)
+ .setView(view)
+ .setTitle(R.string.credentials_unlock)
+ .setPositiveButton(android.R.string.ok, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
+ dialog.setOnDismissListener(this);
+ dialog.show();
+ mButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ mButton.setEnabled(false);
+ }
+
+ @Override public void afterTextChanged(Editable editable) {
+ mButton.setEnabled(mOldPassword == null || mOldPassword.getText().length() > 0);
+ }
+
+ @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override public void onTextChanged(CharSequence s,int start, int before, int count) {
+ }
+
+ @Override public void onClick(DialogInterface dialog, int button) {
+ mUnlockConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
+ }
+
+ @Override public void onDismiss(DialogInterface dialog) {
+ if (mUnlockConfirmed) {
+ mUnlockConfirmed = false;
+ mError.setVisibility(View.VISIBLE);
+ mKeyStore.unlock(mOldPassword.getText().toString());
+ int error = mKeyStore.getLastError();
+ if (error == KeyStore.NO_ERROR) {
+ mRetriesRemaining = -1;
+ Toast.makeText(CredentialStorage.this,
+ R.string.credentials_enabled,
+ Toast.LENGTH_SHORT).show();
+ // aha, now we are unlocked, switch to key guard.
+ // we'll end up back in onResume to install
+ ensureKeyGuard();
+ } else if (error == KeyStore.UNINITIALIZED) {
+ mRetriesRemaining = -1;
+ Toast.makeText(CredentialStorage.this,
+ R.string.credentials_erased,
+ Toast.LENGTH_SHORT).show();
+ // we are reset, we can now set new password with key guard
+ handleUnlockOrInstall();
+ } else if (error >= KeyStore.WRONG_PASSWORD) {
+ // we need to try again
+ mRetriesRemaining = error - KeyStore.WRONG_PASSWORD + 1;
+ handleUnlockOrInstall();
}
- ((AlertDialog) dialog).show();
return;
}
+ finish();
}
- finish();
}
}
diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java
index 10fa8ac..a9002fa 100644
--- a/src/com/android/settings/CryptKeeperSettings.java
+++ b/src/com/android/settings/CryptKeeperSettings.java
@@ -37,16 +37,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
-/**
- * Confirm and execute a reset of the device to a clean "just out of the box"
- * state. Multiple confirmations are required: first, a general "are you sure
- * you want to do this?" prompt, followed by a keyguard pattern trace if the user
- * has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
- * ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is
- * locked, et cetera, then the confirmation sequence is abandoned.
- *
- * This is the initial screen.
- */
public class CryptKeeperSettings extends Fragment {
private static final String TAG = "CryptKeeper";
@@ -54,7 +44,7 @@ public class CryptKeeperSettings extends Fragment {
// This is the minimum acceptable password quality. If the current password quality is
// lower than this, encryption should not be activated.
- private static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+ static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
// Minimum battery charge level (in percent) to launch encryption. If the battery charge is
// lower than this, encryption should not be activated.
@@ -163,7 +153,7 @@ 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()).getKeyguardStoredPasswordQuality();
+ int quality = new LockPatternUtils(getActivity()).getActivePasswordQuality();
if (quality < MIN_PASSWORD_QUALITY) {
return false;
}
@@ -186,7 +176,7 @@ public class CryptKeeperSettings extends Fragment {
// If the user entered a valid keyguard trace, present the final
// confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK && data != null) {
- String password = data.getStringExtra("password");
+ String password = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
if (!TextUtils.isEmpty(password)) {
showFinalConfirmation(password);
}
diff --git a/src/com/android/settings/DateTimeSettingsSetupWizard.java b/src/com/android/settings/DateTimeSettingsSetupWizard.java
index 670fcbc..0c4a301 100644
--- a/src/com/android/settings/DateTimeSettingsSetupWizard.java
+++ b/src/com/android/settings/DateTimeSettingsSetupWizard.java
@@ -27,7 +27,6 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
-import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
@@ -41,6 +40,7 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.ListPopupWindow;
import android.widget.SimpleAdapter;
+import android.widget.TextView;
import android.widget.TimePicker;
import java.util.Calendar;
@@ -119,8 +119,9 @@ public class DateTimeSettingsSetupWizard extends Activity
mAutoDateTimeButton = (CompoundButton)findViewById(R.id.date_time_auto_button);
mAutoDateTimeButton.setChecked(autoDateTimeEnabled);
- mAutoDateTimeButton.setText(autoDateTimeEnabled ? R.string.date_time_auto_summaryOn :
- R.string.date_time_auto_summaryOff);
+ ((TextView)findViewById(R.id.date_time_auto_text))
+ .setText(autoDateTimeEnabled ? R.string.date_time_auto_summaryOn :
+ R.string.date_time_auto_summaryOff);
mAutoDateTimeButton.setOnCheckedChangeListener(this);
mTimePicker = (TimePicker)findViewById(R.id.time_picker);
diff --git a/src/com/android/settings/DefaultRingtonePreference.java b/src/com/android/settings/DefaultRingtonePreference.java
index 0933d62..0801b1f 100644
--- a/src/com/android/settings/DefaultRingtonePreference.java
+++ b/src/com/android/settings/DefaultRingtonePreference.java
@@ -23,7 +23,6 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.RingtonePreference;
import android.util.AttributeSet;
-import android.util.Config;
import android.util.Log;
public class DefaultRingtonePreference extends RingtonePreference {
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index cdb0147..682184e 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -18,9 +18,17 @@ package com.android.settings;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.Configuration;
+
+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;
@@ -46,11 +54,15 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
private static final String KEY_ANIMATIONS = "animations";
private static final String KEY_ACCELEROMETER = "accelerometer";
+ private static final String KEY_FONT_SIZE = "font_size";
private ListPreference mAnimations;
private CheckBoxPreference mAccelerometer;
private float[] mAnimationScales;
+ private ListPreference mFontSizePref;
+ private final Configuration mCurConfig = new Configuration();
+
private IWindowManager mWindowManager;
private ListPreference mScreenTimeoutPreference;
@@ -70,6 +82,12 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
addPreferencesFromResource(R.xml.display_settings);
+ // Fetch this once before attaching a listener for changes.
+ try {
+ mAnimationScales = mWindowManager.getAnimationScales();
+ } catch (RemoteException e) {
+ // Shouldn't happen and not much can be done anyway.
+ }
mAnimations = (ListPreference) findPreference(KEY_ANIMATIONS);
mAnimations.setOnPreferenceChangeListener(this);
mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER);
@@ -81,22 +99,42 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout));
mScreenTimeoutPreference.setOnPreferenceChangeListener(this);
disableUnusableTimeouts(mScreenTimeoutPreference);
- updateTimeoutPreferenceDescription(resolver, currentTimeout);
+ updateTimeoutPreferenceDescription(resolver, mScreenTimeoutPreference,
+ R.string.screen_timeout_summary, currentTimeout);
+
+ mFontSizePref = (ListPreference) findPreference(KEY_FONT_SIZE);
+ mFontSizePref.setOnPreferenceChangeListener(this);
}
- private void updateTimeoutPreferenceDescription(ContentResolver resolver, long currentTimeout) {
- final CharSequence[] entries = mScreenTimeoutPreference.getEntries();
- final CharSequence[] values = mScreenTimeoutPreference.getEntryValues();
- int best = 0;
- for (int i = 0; i < values.length; i++) {
- long timeout = Long.valueOf(values[i].toString());
- if (currentTimeout >= timeout) {
- best = i;
+ private void updateTimeoutPreferenceDescription(
+ ContentResolver resolver,
+ ListPreference pref,
+ int summaryStrings,
+ long currentTimeout) {
+ updateTimeoutPreferenceDescription(resolver, pref, summaryStrings, 0, currentTimeout);
+ }
+ private void updateTimeoutPreferenceDescription(
+ ContentResolver resolver,
+ ListPreference pref,
+ int summaryStrings,
+ int zeroString,
+ long currentTimeout) {
+ String summary;
+ if (currentTimeout == 0) {
+ summary = pref.getContext().getString(zeroString);
+ } else {
+ final CharSequence[] entries = pref.getEntries();
+ final CharSequence[] values = pref.getEntryValues();
+ int best = 0;
+ for (int i = 0; i < values.length; i++) {
+ long timeout = Long.valueOf(values[i].toString());
+ if (currentTimeout >= timeout) {
+ best = i;
+ }
}
+ summary = pref.getContext().getString(summaryStrings, entries[best]);
}
- String summary = mScreenTimeoutPreference.getContext()
- .getString(R.string.screen_timeout_summary, entries[best]);
- mScreenTimeoutPreference.setSummary(summary);
+ pref.setSummary(summary);
}
private void disableUnusableTimeouts(ListPreference screenTimeoutPreference) {
@@ -135,6 +173,29 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
screenTimeoutPreference.setEnabled(revisedEntries.size() > 0);
}
+ int floatToIndex(float val, int resid) {
+ String[] indices = getResources().getStringArray(resid);
+ float lastVal = Float.parseFloat(indices[0]);
+ for (int i=1; i<indices.length; i++) {
+ float thisVal = Float.parseFloat(indices[i]);
+ if (val < (lastVal + (thisVal-lastVal)*.5f)) {
+ return i-1;
+ }
+ lastVal = thisVal;
+ }
+ return indices.length-1;
+ }
+
+ public void readFontSizePreference(ListPreference pref) {
+ try {
+ mCurConfig.updateFrom(
+ ActivityManagerNative.getDefault().getConfiguration());
+ } catch (RemoteException e) {
+ }
+ pref.setValueIndex(floatToIndex(mCurConfig.fontScale,
+ R.array.entryvalues_font_size));
+ }
+
@Override
public void onResume() {
super.onResume();
@@ -157,6 +218,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
try {
mAnimationScales = mWindowManager.getAnimationScales();
} catch (RemoteException e) {
+ // Shouldn't happen and not much can be done anyway.
}
if (mAnimationScales != null) {
if (mAnimationScales.length >= 1) {
@@ -179,6 +241,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
mAnimations.setValueIndex(idx);
updateAnimationsSummary(mAnimations.getValue());
updateAccelerometerRotationCheckbox();
+ readFontSizePreference(mFontSizePref);
}
private void updateAccelerometerRotationCheckbox() {
@@ -200,6 +263,14 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
}
}
+ public void writeFontSizePreference(Object objValue) {
+ try {
+ mCurConfig.fontScale = Float.parseFloat(objValue.toString());
+ ActivityManagerNative.getDefault().updateConfiguration(mCurConfig);
+ } catch (RemoteException e) {
+ }
+ }
+
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference == mAccelerometer) {
@@ -207,7 +278,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
Settings.System.ACCELEROMETER_ROTATION,
mAccelerometer.isChecked() ? 1 : 0);
}
- return true;
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
}
public boolean onPreferenceChange(Preference preference, Object objValue) {
@@ -236,11 +307,15 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
try {
Settings.System.putInt(getContentResolver(),
SCREEN_OFF_TIMEOUT, value);
- updateTimeoutPreferenceDescription(getContentResolver(), value);
+ updateTimeoutPreferenceDescription(getContentResolver(), mScreenTimeoutPreference,
+ R.string.screen_timeout_summary, value);
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist screen timeout setting", e);
}
}
+ if (KEY_FONT_SIZE.equals(key)) {
+ writeFontSizePreference(objValue);
+ }
return true;
}
diff --git a/src/com/android/settings/DreamComponentPreference.java b/src/com/android/settings/DreamComponentPreference.java
new file mode 100644
index 0000000..3bc0eb4
--- /dev/null
+++ b/src/com/android/settings/DreamComponentPreference.java
@@ -0,0 +1,139 @@
+/*
+ * 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.DREAM_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 DreamComponentPreference extends Preference {
+ private static final String TAG = "DreamComponentPreference";
+
+ 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, DREAM_COMPONENT);
+ if (component != null) {
+ ComponentName cn = ComponentName.unflattenFromString(component);
+ try {
+ setSummary(pm.getActivityInfo(cn, 0).loadLabel(pm));
+ } catch (PackageManager.NameNotFoundException ex) {
+ setSummary("(unknown)");
+ }
+ }
+ }
+
+ 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));
+ }
+
+ @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, DREAM_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..7ddab31
--- /dev/null
+++ b/src/com/android/settings/DreamSettings.java
@@ -0,0 +1,128 @@
+/*
+ * 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.DREAM_TIMEOUT;
+
+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.PreferenceScreen;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.IWindowManager;
+
+import java.util.ArrayList;
+
+public class DreamSettings extends SettingsPreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ private static final String TAG = "DreamSettings";
+
+ private static final String KEY_DREAM_TIMEOUT = "dream_timeout";
+
+ private ListPreference mScreenTimeoutPreference;
+ private ListPreference mDreamTimeoutPreference;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ContentResolver resolver = getActivity().getContentResolver();
+
+ addPreferencesFromResource(R.xml.dream_settings);
+
+ mDreamTimeoutPreference = (ListPreference) findPreference(KEY_DREAM_TIMEOUT);
+ final long currentSaverTimeout = Settings.Secure.getLong(resolver, DREAM_TIMEOUT,
+ 0);
+ mDreamTimeoutPreference.setValue(String.valueOf(currentSaverTimeout));
+ mDreamTimeoutPreference.setOnPreferenceChangeListener(this);
+ updateTimeoutPreferenceDescription(resolver, mDreamTimeoutPreference,
+ R.string.dream_timeout_summary,
+ R.string.dream_timeout_zero_summary,
+ currentSaverTimeout);
+ }
+
+ private void updateTimeoutPreferenceDescription(
+ ContentResolver resolver,
+ ListPreference pref,
+ int summaryStrings,
+ long currentTimeout) {
+ updateTimeoutPreferenceDescription(resolver, pref, summaryStrings, 0, currentTimeout);
+ }
+ private void updateTimeoutPreferenceDescription(
+ ContentResolver resolver,
+ ListPreference pref,
+ int summaryStrings,
+ int zeroString,
+ long currentTimeout) {
+ String summary;
+ if (currentTimeout == 0) {
+ summary = pref.getContext().getString(zeroString);
+ } else {
+ final CharSequence[] entries = pref.getEntries();
+ final CharSequence[] values = pref.getEntryValues();
+ int best = 0;
+ for (int i = 0; i < values.length; i++) {
+ long timeout = Long.valueOf(values[i].toString());
+ if (currentTimeout >= timeout) {
+ best = i;
+ }
+ }
+ summary = pref.getContext().getString(summaryStrings, entries[best]);
+ }
+ pref.setSummary(summary);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ public boolean onPreferenceChange(Preference preference, Object objValue) {
+ final String key = preference.getKey();
+ if (KEY_DREAM_TIMEOUT.equals(key)) {
+ int value = Integer.parseInt((String) objValue);
+ try {
+ Settings.Secure.putInt(getContentResolver(),
+ DREAM_TIMEOUT, value);
+ updateTimeoutPreferenceDescription(getContentResolver(),
+ mDreamTimeoutPreference,
+ R.string.dream_timeout_summary,
+ R.string.dream_timeout_zero_summary,
+ value);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "could not persist dream timeout setting", e);
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/src/com/android/settings/DreamTesterPreference.java b/src/com/android/settings/DreamTesterPreference.java
new file mode 100644
index 0000000..7ff5667
--- /dev/null
+++ b/src/com/android/settings/DreamTesterPreference.java
@@ -0,0 +1,75 @@
+/*
+ * 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.DREAM_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, DREAM_COMPONENT);
+ if (component != null) {
+ ComponentName cn = ComponentName.unflattenFromString(component);
+ Intent intent = new Intent(Intent.ACTION_MAIN)
+ .setComponent(cn)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP)
+ .putExtra("android.dreams.TEST", true);
+ getContext().startActivity(intent);
+ }
+ }
+}
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index ba07fb5..d45616e 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -24,11 +24,11 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
+import android.net.TrafficStats;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
-import android.os.INetStatService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -133,7 +133,6 @@ public class RadioInfo extends Activity {
private TelephonyManager mTelephonyManager;
private Phone phone = null;
private PhoneStateIntentReceiver mPhoneStateReceiver;
- private INetStatService netstat;
private String mPingIpAddrResult;
private String mPingHostnameResult;
@@ -311,8 +310,6 @@ public class RadioInfo extends Activity {
phone.getNeighboringCids(
mHandler.obtainMessage(EVENT_QUERY_NEIGHBORING_CIDS_DONE));
- netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
-
CellLocation.requestLocationUpdate();
}
@@ -625,19 +622,16 @@ public class RadioInfo extends Activity {
private final void updateDataStats2() {
Resources r = getResources();
- try {
- long txPackets = netstat.getMobileTxPackets();
- long rxPackets = netstat.getMobileRxPackets();
- long txBytes = netstat.getMobileTxBytes();
- long rxBytes = netstat.getMobileRxBytes();
+ long txPackets = TrafficStats.getMobileTxPackets();
+ long rxPackets = TrafficStats.getMobileRxPackets();
+ long txBytes = TrafficStats.getMobileTxBytes();
+ long rxBytes = TrafficStats.getMobileRxBytes();
- String packets = r.getString(R.string.radioInfo_display_packets);
- String bytes = r.getString(R.string.radioInfo_display_bytes);
+ String packets = r.getString(R.string.radioInfo_display_packets);
+ String bytes = r.getString(R.string.radioInfo_display_bytes);
- sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
- received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
- } catch (RemoteException e) {
- }
+ sent.setText(txPackets + " " + packets + ", " + txBytes + " " + bytes);
+ received.setText(rxPackets + " " + packets + ", " + rxBytes + " " + bytes);
}
/**
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index dc4c42b..5d77e53 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -70,7 +70,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
// Misc Settings
private static final String KEY_SIM_LOCK = "sim_lock";
private static final String KEY_SHOW_PASSWORD = "show_password";
- private static final String KEY_ENABLE_CREDENTIALS = "enable_credentials";
private static final String KEY_RESET_CREDENTIALS = "reset_credentials";
private static final String TAG = "SecuritySettings";
@@ -98,7 +97,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
private CheckBoxPreference mShowPassword;
- private CheckBoxPreference mEnableCredentials;
private Preference mResetCredentials;
@Override
@@ -239,8 +237,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
mShowPassword = (CheckBoxPreference) root.findPreference(KEY_SHOW_PASSWORD);
// Credential storage
- mEnableCredentials = (CheckBoxPreference) root.findPreference(KEY_ENABLE_CREDENTIALS);
- mEnableCredentials.setOnPreferenceChangeListener(this);
mResetCredentials = root.findPreference(KEY_RESET_CREDENTIALS);
return root;
@@ -337,10 +333,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
mShowPassword.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) != 0);
- int state = KeyStore.getInstance().test();
- mEnableCredentials.setChecked(state == KeyStore.NO_ERROR);
- mEnableCredentials.setEnabled(state != KeyStore.UNINITIALIZED);
- mResetCredentials.setEnabled(state != KeyStore.UNINITIALIZED);
+ KeyStore.State state = KeyStore.getInstance().state();
+ mResetCredentials.setEnabled(state != KeyStore.State.UNINITIALIZED);
}
@Override
@@ -430,13 +424,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
// activity will be restated and the new value re-read, so the checkbox will get its
// new value then.
return false;
- } else if (preference == mEnableCredentials) {
- if (value != null && (Boolean) value) {
- getActivity().startActivity(new Intent(CredentialStorage.ACTION_UNLOCK));
- return false;
- } else {
- KeyStore.getInstance().lock();
- }
}
return true;
}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 2532747..c68ea5d 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -229,6 +229,15 @@ public class Settings extends PreferenceActivity implements ButtonBarHandler {
return super.onGetInitialHeader();
}
+ @Override
+ public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
+ int titleRes, int shortTitleRes) {
+ Intent intent = super.onBuildStartFragmentIntent(fragmentName, args,
+ titleRes, shortTitleRes);
+ intent.setClass(this, SubSettings.class);
+ return intent;
+ }
+
/**
* Populate the activity with the top-level headers.
*/
diff --git a/src/com/android/settings/SettingsCheckBoxPreference.java b/src/com/android/settings/SettingsCheckBoxPreference.java
new file mode 100644
index 0000000..6acdfe8
--- /dev/null
+++ b/src/com/android/settings/SettingsCheckBoxPreference.java
@@ -0,0 +1,91 @@
+/*
+ * 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 android.content.Context;
+import android.content.Intent;
+import android.preference.CheckBoxPreference;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+
+/**
+ * CheckBox preference that optionally shows an icon for launching a settings
+ * {@link android.app.Activity}. The settings activity, if intent for launching
+ * it was provided, can be stared only if the CheckBox in is checked.
+ */
+public class SettingsCheckBoxPreference extends CheckBoxPreference {
+
+ // Integer.MIN_VALUE means not initalized
+ private static int sDimAlpha = Integer.MIN_VALUE;
+
+ private final Intent mSettingsIntent;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param context Context for accessing resources.
+ * @param settingsIntent Intent to use as settings for the item represented by
+ * this preference. Pass <code>null</code> if there is no associated
+ * settings activity.
+ */
+ public SettingsCheckBoxPreference(Context context, Intent settingsIntent) {
+ super(context);
+
+ if (sDimAlpha == Integer.MIN_VALUE) {
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
+ sDimAlpha = (int) (outValue.getFloat() * 255);
+ }
+
+ mSettingsIntent = settingsIntent;
+ setWidgetLayoutResource(R.layout.preference_settings_checkbox_widget);
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ ImageView settingsButton = (ImageView) view.findViewById(R.id.settings_button);
+ if (settingsButton == null) {
+ return;
+ }
+ if (mSettingsIntent != null) {
+ CheckBox checkbox = (CheckBox) view.findViewById(com.android.internal.R.id.checkbox);
+ if (checkbox == null) {
+ return;
+ }
+ if (checkbox.isChecked()) {
+ settingsButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View view) {
+ getContext().startActivity(mSettingsIntent);
+ }
+ });
+ }
+ settingsButton.setVisibility(View.VISIBLE);
+ if (checkbox.isChecked() && isEnabled()) {
+ settingsButton.setAlpha(255);
+ } else {
+ settingsButton.setAlpha(sDimAlpha);
+ }
+ } else {
+ settingsButton.setVisibility(View.GONE);
+ }
+ }
+}
diff --git a/src/com/android/settings/SettingsLicenseActivity.java b/src/com/android/settings/SettingsLicenseActivity.java
index 99828ce..2960180 100644
--- a/src/com/android/settings/SettingsLicenseActivity.java
+++ b/src/com/android/settings/SettingsLicenseActivity.java
@@ -21,7 +21,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.text.TextUtils;
-import android.util.Config;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -46,7 +45,7 @@ import java.util.zip.GZIPInputStream;
public class SettingsLicenseActivity extends Activity {
private static final String TAG = "SettingsLicenseActivity";
- private static final boolean LOGV = false || Config.LOGV;
+ private static final boolean LOGV = false || false;
private static final String DEFAULT_LICENSE_PATH = "/system/etc/NOTICE.html.gz";
private static final String PROPERTY_LICENSE_PATH = "ro.config.license_path";
diff --git a/src/com/android/settings/SubSettings.java b/src/com/android/settings/SubSettings.java
new file mode 100644
index 0000000..9cd3c31
--- /dev/null
+++ b/src/com/android/settings/SubSettings.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+/**
+ * Stub class for showing sub-settings; we can't use the main Settings class
+ * since for our app it is a special singleTask class.
+ */
+public class SubSettings extends Settings {
+}
diff --git a/src/com/android/settings/TestingSettingsBroadcastReceiver.java b/src/com/android/settings/TestingSettingsBroadcastReceiver.java
index c6cd7e1..cea12c5 100644
--- a/src/com/android/settings/TestingSettingsBroadcastReceiver.java
+++ b/src/com/android/settings/TestingSettingsBroadcastReceiver.java
@@ -6,7 +6,6 @@ import static android.provider.Telephony.Intents.SECRET_CODE_ACTION;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
-import android.util.Config;
import android.util.Log;
import android.view.KeyEvent;
diff --git a/src/com/android/settings/TextToSpeechSettings.java b/src/com/android/settings/TextToSpeechSettings.java
index 62edac9..1a63272 100644
--- a/src/com/android/settings/TextToSpeechSettings.java
+++ b/src/com/android/settings/TextToSpeechSettings.java
@@ -24,25 +24,23 @@ import static android.provider.Settings.Secure.TTS_DEFAULT_VARIANT;
import static android.provider.Settings.Secure.TTS_ENABLED_PLUGINS;
import static android.provider.Settings.Secure.TTS_USE_DEFAULTS;
-import android.app.Activity;
import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Context;
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.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
-import android.preference.PreferenceGroup;
-import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceGroup;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.speech.tts.TextToSpeech;
+import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
@@ -54,9 +52,9 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
TextToSpeech.OnInitListener {
+ private static final boolean DBG = true;
private static final String TAG = "TextToSpeechSettings";
- private static final String SYSTEM_TTS = "com.svox.pico";
private static final String KEY_TTS_PLAY_EXAMPLE = "tts_play_example";
private static final String KEY_TTS_INSTALL_DATA = "tts_install_data";
private static final String KEY_TTS_USE_DEFAULT = "toggle_use_default_tts_settings";
@@ -65,6 +63,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
private static final String KEY_TTS_DEFAULT_COUNTRY = "tts_default_country";
private static final String KEY_TTS_DEFAULT_VARIANT = "tts_default_variant";
private static final String KEY_TTS_DEFAULT_SYNTH = "tts_default_synth";
+ private static final String KEY_TTS_ENGINES = "tts_engines_section";
private static final String KEY_PLUGIN_ENABLED_PREFIX = "ENABLED_";
private static final String KEY_PLUGIN_SETTINGS_PREFIX = "SETTINGS_";
@@ -76,19 +75,17 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
private static final String LOCALE_DELIMITER = "-";
- private static final String FALLBACK_TTS_DEFAULT_SYNTH =
- TextToSpeech.Engine.DEFAULT_SYNTH;
-
private Preference mPlayExample = null;
private Preference mInstallData = null;
private CheckBoxPreference mUseDefaultPref = null;
private ListPreference mDefaultRatePref = null;
private ListPreference mDefaultLocPref = null;
private ListPreference mDefaultSynthPref = null;
+ private PreferenceGroup mEnginesGroup;
+
private String mDefaultLanguage = null;
private String mDefaultCountry = null;
private String mDefaultLocVariant = null;
- private String mDefaultEng = "";
private int mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
// Index of the current string to use for the demo.
@@ -112,10 +109,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.tts_settings);
- final Activity activity = getActivity();
- addEngineSpecificSettings(activity);
-
- activity.setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
+ getActivity().setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
mEnableDemo = false;
mTtsStarted = false;
@@ -125,10 +119,24 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
mDefaultCountry = currentLocale.getISO3Country();
mDefaultLocVariant = currentLocale.getVariant();
- mTts = new TextToSpeech(activity, this);
- initClickers();
- }
+ mPlayExample = findPreference(KEY_TTS_PLAY_EXAMPLE);
+ mPlayExample.setOnPreferenceClickListener(this);
+
+ mInstallData = findPreference(KEY_TTS_INSTALL_DATA);
+ mInstallData.setOnPreferenceClickListener(this);
+
+ mUseDefaultPref = (CheckBoxPreference) findPreference(KEY_TTS_USE_DEFAULT);
+ mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH);
+ mDefaultRatePref = (ListPreference) findPreference(KEY_TTS_DEFAULT_RATE);
+ mDefaultLocPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_LANG);
+ mEnginesGroup = (PreferenceGroup) findPreference(KEY_TTS_ENGINES);
+
+ mTts = new TextToSpeech(getActivity().getApplicationContext(), this);
+
+ initDefaultSettings();
+ addEngineSpecificSettings();
+ }
@Override
public void onStart() {
@@ -142,7 +150,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
}
}
-
@Override
public void onDestroy() {
super.onDestroy();
@@ -165,64 +172,53 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
}
}
- private void addEngineSpecificSettings(Context context) {
- PreferenceGroup enginesCategory = (PreferenceGroup) findPreference("tts_engines_section");
- Intent intent = new Intent("android.intent.action.START_TTS_ENGINE");
- ResolveInfo[] enginesArray = new ResolveInfo[0];
- PackageManager pm = getPackageManager();
- enginesArray = pm.queryIntentActivities(intent, 0).toArray(enginesArray);
- for (int i = 0; i < enginesArray.length; i++) {
+ private void addEngineSpecificSettings() {
+ Context context = getActivity();
+ List<TextToSpeech.EngineInfo> engines = mTts.getEngines();
+ for (TextToSpeech.EngineInfo engine : engines) {
String prefKey = "";
- final String pluginPackageName = enginesArray[i].activityInfo.packageName;
- if (!enginesArray[i].activityInfo.packageName.equals(SYSTEM_TTS)) {
- CheckBoxPreference chkbxPref = new CheckBoxPreference(context);
- prefKey = KEY_PLUGIN_ENABLED_PREFIX + pluginPackageName;
- chkbxPref.setKey(prefKey);
- chkbxPref.setTitle(enginesArray[i].loadLabel(pm));
- enginesCategory.addPreference(chkbxPref);
+ final String engineName = engine.name;
+ if (!engineName.equals(TextToSpeech.Engine.DEFAULT_ENGINE)) {
+ CheckBoxPreference enablePref = new CheckBoxPreference(context);
+ prefKey = KEY_PLUGIN_ENABLED_PREFIX + engineName;
+ enablePref.setKey(prefKey);
+ enablePref.setTitle(engine.label);
+ enablePref.setOnPreferenceClickListener(this);
+ mEnginesGroup.addPreference(enablePref);
}
- if (pluginHasSettings(pluginPackageName)) {
+ if (engineHasSettings(engineName)) {
Preference pref = new Preference(context);
- prefKey = KEY_PLUGIN_SETTINGS_PREFIX + pluginPackageName;
+ prefKey = KEY_PLUGIN_SETTINGS_PREFIX + engineName;
pref.setKey(prefKey);
- pref.setTitle(enginesArray[i].loadLabel(pm));
+ pref.setTitle(engine.label);
CharSequence settingsLabel = getResources().getString(
- R.string.tts_engine_name_settings, enginesArray[i].loadLabel(pm));
+ R.string.tts_engine_name_settings, engine.label);
pref.setSummary(settingsLabel);
- pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
- public boolean onPreferenceClick(Preference preference){
+ // TODO: Add a new API for this.
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
Intent i = new Intent();
- i.setClassName(pluginPackageName,
- pluginPackageName + ".EngineSettings");
+ i.setClassName(engineName,
+ engineName + ".EngineSettings");
startActivity(i);
return true;
}
});
- enginesCategory.addPreference(pref);
+ mEnginesGroup.addPreference(pref);
}
}
}
- private boolean pluginHasSettings(String pluginPackageName) {
+ private boolean engineHasSettings(String enginePackageName) {
PackageManager pm = getPackageManager();
Intent i = new Intent();
- i.setClassName(pluginPackageName, pluginPackageName + ".EngineSettings");
+ i.setClassName(enginePackageName, enginePackageName + ".EngineSettings");
if (pm.resolveActivity(i, PackageManager.MATCH_DEFAULT_ONLY) != null){
return true;
}
return false;
}
-
- private void initClickers() {
- mPlayExample = findPreference(KEY_TTS_PLAY_EXAMPLE);
- mPlayExample.setOnPreferenceClickListener(this);
-
- mInstallData = findPreference(KEY_TTS_INSTALL_DATA);
- mInstallData.setOnPreferenceClickListener(this);
- }
-
-
private void initDefaultSettings() {
ContentResolver resolver = getContentResolver();
@@ -230,32 +226,16 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
// settings if they are not found.
// "Use Defaults"
- int useDefault = 0;
- mUseDefaultPref = (CheckBoxPreference) findPreference(KEY_TTS_USE_DEFAULT);
- try {
- useDefault = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS);
- } catch (SettingNotFoundException e) {
- // "use default" setting not found, initialize it
- useDefault = TextToSpeech.Engine.USE_DEFAULTS;
- Settings.Secure.putInt(resolver, TTS_USE_DEFAULTS, useDefault);
- }
+ int useDefault = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS,
+ TextToSpeech.Engine.USE_DEFAULTS);
mUseDefaultPref.setChecked(useDefault == 1);
mUseDefaultPref.setOnPreferenceChangeListener(this);
// Default synthesis engine
- mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH);
loadEngines();
mDefaultSynthPref.setOnPreferenceChangeListener(this);
- String engine = Settings.Secure.getString(resolver, TTS_DEFAULT_SYNTH);
- if (engine == null) {
- // TODO move FALLBACK_TTS_DEFAULT_SYNTH to TextToSpeech
- engine = FALLBACK_TTS_DEFAULT_SYNTH;
- Settings.Secure.putString(resolver, TTS_DEFAULT_SYNTH, engine);
- }
- mDefaultEng = engine;
// Default rate
- mDefaultRatePref = (ListPreference) findPreference(KEY_TTS_DEFAULT_RATE);
try {
mDefaultRate = Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE);
} catch (SettingNotFoundException e) {
@@ -265,34 +245,27 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
}
mDefaultRatePref.setValue(String.valueOf(mDefaultRate));
mDefaultRatePref.setOnPreferenceChangeListener(this);
- // apply the default rate so the TTS demo in the Settings screen uses it, even if
- // the use of default settings is not enforced
- mTts.setSpeechRate(mDefaultRate/100.0f);
// Default language / country / variant : these three values map to a single ListPref
// representing the matching Locale
- mDefaultLocPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_LANG);
initDefaultLang();
mDefaultLocPref.setOnPreferenceChangeListener(this);
}
-
/**
* Ask the current default engine to launch the matching CHECK_TTS_DATA activity
* to check the required TTS files are properly installed.
*/
private void checkVoiceData() {
- PackageManager pm = getPackageManager();
- Intent intent = new Intent();
- intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
- // query only the package that matches that of the default engine
- for (int i = 0; i < resolveInfos.size(); i++) {
- ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
- if (mDefaultEng.equals(currentActivityInfo.packageName)) {
- intent.setClassName(mDefaultEng, currentActivityInfo.name);
- this.startActivityForResult(intent, VOICE_DATA_INTEGRITY_CHECK);
- }
+ String defaultEngine = mTts.getDefaultEngine();
+ if (TextUtils.isEmpty(defaultEngine)) return;
+ Intent intent = new Intent(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
+ intent.setPackage(defaultEngine);
+ try {
+ Log.v(TAG, "Checking voice data: " + intent.toUri(0));
+ startActivityForResult(intent, VOICE_DATA_INTEGRITY_CHECK);
+ } catch (ActivityNotFoundException ex) {
+ Log.e(TAG, "Failed to check TTS data, no acitivty found for " + intent + ")");
}
}
@@ -302,18 +275,16 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
* so the required TTS files are properly installed.
*/
private void installVoiceData() {
- PackageManager pm = getPackageManager();
- Intent intent = new Intent();
- intent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
+ String defaultEngine = mTts.getDefaultEngine();
+ if (TextUtils.isEmpty(defaultEngine)) return;
+ Intent intent = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
- // query only the package that matches that of the default engine
- for (int i = 0; i < resolveInfos.size(); i++) {
- ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
- if (mDefaultEng.equals(currentActivityInfo.packageName)) {
- intent.setClassName(mDefaultEng, currentActivityInfo.name);
- this.startActivity(intent);
- }
+ intent.setPackage(defaultEngine);
+ try {
+ Log.v(TAG, "Installing voice data: " + intent.toUri(0));
+ startActivity(intent);
+ } catch (ActivityNotFoundException ex) {
+ Log.e(TAG, "Failed to install TTS data, no acitivty found for " + intent + ")");
}
}
@@ -322,26 +293,21 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
* spoken to the user.
*/
private void getSampleText() {
- PackageManager pm = getPackageManager();
- Intent intent = new Intent();
- // TODO (clchen): Replace Intent string with the actual
- // Intent defined in the list of platform Intents.
- intent.setAction("android.speech.tts.engine.GET_SAMPLE_TEXT");
+ String defaultEngine = mTts.getDefaultEngine();
+ if (TextUtils.isEmpty(defaultEngine)) return;
+ Intent intent = new Intent(TextToSpeech.Engine.ACTION_GET_SAMPLE_TEXT);
intent.putExtra("language", mDefaultLanguage);
intent.putExtra("country", mDefaultCountry);
intent.putExtra("variant", mDefaultLocVariant);
- List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
- // query only the package that matches that of the default engine
- for (int i = 0; i < resolveInfos.size(); i++) {
- ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
- if (mDefaultEng.equals(currentActivityInfo.packageName)) {
- intent.setClassName(mDefaultEng, currentActivityInfo.name);
- this.startActivityForResult(intent, GET_SAMPLE_TEXT);
- }
+ intent.setPackage(defaultEngine);
+ try {
+ Log.v(TAG, "Getting sample text: " + intent.toUri(0));
+ startActivityForResult(intent, GET_SAMPLE_TEXT);
+ } catch (ActivityNotFoundException ex) {
+ Log.e(TAG, "Failed to get sample text, no acitivty found for " + intent + ")");
}
}
-
/**
* Called when the TTS engine is initialized.
*/
@@ -358,7 +324,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
mDefaultLocVariant = new String();
}
mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
- initDefaultSettings();
updateWidgetState();
checkVoiceData();
mTtsStarted = true;
@@ -370,142 +335,155 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
updateWidgetState();
}
-
/**
* Called when voice data integrity check returns
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == VOICE_DATA_INTEGRITY_CHECK) {
- if (data == null){
- // The CHECK_TTS_DATA activity for the plugin did not run properly;
- // disable the preview and install controls and return.
- mEnableDemo = false;
- mVoicesMissing = false;
- updateWidgetState();
- return;
- }
- ArrayList<String> available =
- data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
- ArrayList<String> unavailable =
- data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);
- if ((available == null) || (unavailable == null)){
- // The CHECK_TTS_DATA activity for the plugin did not run properly;
- // disable the preview and install controls and return.
- mEnableDemo = false;
- mVoicesMissing = false;
- updateWidgetState();
- return;
+ onVoiceDataIntegrityCheckDone(data);
+ } else if (requestCode == GET_SAMPLE_TEXT) {
+ onSampleTextReceived(resultCode, data);
+ }
+ }
+
+ private void onVoiceDataIntegrityCheckDone(Intent data) {
+ if (data == null){
+ Log.e(TAG, "TTS data check failed data = null");
+ // The CHECK_TTS_DATA activity for the plugin did not run properly;
+ // disable the preview and install controls and return.
+ mEnableDemo = false;
+ mVoicesMissing = false;
+ updateWidgetState();
+ return;
+ }
+ Log.v(TAG, "TTS data check completed, data = " + data.toUri(0));
+ ArrayList<String> available =
+ data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
+ ArrayList<String> unavailable =
+ data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);
+ if (available == null || unavailable == null){
+ Log.e(TAG, "TTS data check failed (available == == null)");
+ // The CHECK_TTS_DATA activity for the plugin did not run properly;
+ // disable the preview and install controls and return.
+ mEnableDemo = false;
+ mVoicesMissing = false;
+ updateWidgetState();
+ return;
+ }
+ if (available.size() > 0){
+ if (mTts == null) {
+ mTts = new TextToSpeech(getActivity(), this);
}
- if (available.size() > 0){
- if (mTts == null) {
- mTts = new TextToSpeech(getActivity(), this);
- }
- ListPreference ttsLanguagePref =
- (ListPreference) findPreference("tts_default_lang");
- CharSequence[] entries = new CharSequence[available.size()];
- CharSequence[] entryValues = new CharSequence[available.size()];
- int selectedLanguageIndex = -1;
- String selectedLanguagePref = mDefaultLanguage;
- if (mDefaultCountry.length() > 0) {
- selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
- mDefaultCountry;
- }
- if (mDefaultLocVariant.length() > 0) {
- selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
- mDefaultLocVariant;
- }
- for (int i = 0; i < available.size(); i++) {
- String[] langCountryVariant = available.get(i).split("-");
- Locale loc = null;
- if (langCountryVariant.length == 1){
- loc = new Locale(langCountryVariant[0]);
- } else if (langCountryVariant.length == 2){
- loc = new Locale(langCountryVariant[0], langCountryVariant[1]);
- } else if (langCountryVariant.length == 3){
- loc = new Locale(langCountryVariant[0], langCountryVariant[1],
- langCountryVariant[2]);
- }
- if (loc != null){
- entries[i] = loc.getDisplayName();
- entryValues[i] = available.get(i);
- if (entryValues[i].equals(selectedLanguagePref)) {
- selectedLanguageIndex = i;
- }
- }
- }
- ttsLanguagePref.setEntries(entries);
- ttsLanguagePref.setEntryValues(entryValues);
- if (selectedLanguageIndex > -1) {
- ttsLanguagePref.setValueIndex(selectedLanguageIndex);
- }
- mEnableDemo = true;
- // Make sure that the default language can be used.
- int languageResult = mTts.setLanguage(
+
+ updateDefaultLocPref(available);
+
+ mEnableDemo = true;
+ // Make sure that the default language can be used.
+ int languageResult = mTts.setLanguage(
+ new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
+ if (languageResult < TextToSpeech.LANG_AVAILABLE){
+ Locale currentLocale = Locale.getDefault();
+ mDefaultLanguage = currentLocale.getISO3Language();
+ mDefaultCountry = currentLocale.getISO3Country();
+ mDefaultLocVariant = currentLocale.getVariant();
+ languageResult = mTts.setLanguage(
new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
+ // If the default Locale isn't supported, just choose the first available
+ // language so that there is at least something.
if (languageResult < TextToSpeech.LANG_AVAILABLE){
- Locale currentLocale = Locale.getDefault();
- mDefaultLanguage = currentLocale.getISO3Language();
- mDefaultCountry = currentLocale.getISO3Country();
- mDefaultLocVariant = currentLocale.getVariant();
- languageResult = mTts.setLanguage(
+ parseLocaleInfo(mDefaultLocPref.getEntryValues()[0].toString());
+ mTts.setLanguage(
new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
- // If the default Locale isn't supported, just choose the first available
- // language so that there is at least something.
- if (languageResult < TextToSpeech.LANG_AVAILABLE){
- parseLocaleInfo(ttsLanguagePref.getEntryValues()[0].toString());
- mTts.setLanguage(
- new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
- }
- ContentResolver resolver = getContentResolver();
- Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, mDefaultLanguage);
- Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, mDefaultCountry);
- Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, mDefaultLocVariant);
}
- } else {
- mEnableDemo = false;
+ ContentResolver resolver = getContentResolver();
+ Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, mDefaultLanguage);
+ Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, mDefaultCountry);
+ Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, mDefaultLocVariant);
}
+ } else {
+ mEnableDemo = false;
+ }
- if (unavailable.size() > 0){
- mVoicesMissing = true;
- } else {
- mVoicesMissing = false;
- }
+ if (unavailable.size() > 0){
+ mVoicesMissing = true;
+ } else {
+ mVoicesMissing = false;
+ }
- updateWidgetState();
- } else if (requestCode == GET_SAMPLE_TEXT) {
- if (resultCode == TextToSpeech.LANG_AVAILABLE) {
- String sample = getActivity().getString(R.string.tts_demo);
- if ((data != null) && (data.getStringExtra("sampleText") != null)) {
- sample = data.getStringExtra("sampleText");
- }
- if (mTts != null) {
- mTts.speak(sample, TextToSpeech.QUEUE_FLUSH, null);
+ updateWidgetState();
+ }
+
+ private void updateDefaultLocPref(ArrayList<String> availableLangs) {
+ CharSequence[] entries = new CharSequence[availableLangs.size()];
+ CharSequence[] entryValues = new CharSequence[availableLangs.size()];
+ int selectedLanguageIndex = -1;
+ String selectedLanguagePref = mDefaultLanguage;
+ if (mDefaultCountry.length() > 0) {
+ selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
+ mDefaultCountry;
+ }
+ if (mDefaultLocVariant.length() > 0) {
+ selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
+ mDefaultLocVariant;
+ }
+ for (int i = 0; i < availableLangs.size(); i++) {
+ String[] langCountryVariant = availableLangs.get(i).split("-");
+ Locale loc = null;
+ if (langCountryVariant.length == 1){
+ loc = new Locale(langCountryVariant[0]);
+ } else if (langCountryVariant.length == 2){
+ loc = new Locale(langCountryVariant[0], langCountryVariant[1]);
+ } else if (langCountryVariant.length == 3){
+ loc = new Locale(langCountryVariant[0], langCountryVariant[1],
+ langCountryVariant[2]);
+ }
+ if (loc != null){
+ entries[i] = loc.getDisplayName();
+ entryValues[i] = availableLangs.get(i);
+ if (entryValues[i].equals(selectedLanguagePref)) {
+ selectedLanguageIndex = i;
}
- } else {
- // TODO: Display an error here to the user.
- Log.e(TAG, "Did not have a sample string for the requested language");
}
}
+ mDefaultLocPref.setEntries(entries);
+ mDefaultLocPref.setEntryValues(entryValues);
+ if (selectedLanguageIndex > -1) {
+ mDefaultLocPref.setValueIndex(selectedLanguageIndex);
+ }
+ }
+
+ private void onSampleTextReceived(int resultCode, Intent data) {
+ if (resultCode == TextToSpeech.LANG_AVAILABLE) {
+ String sample = getActivity().getString(R.string.tts_demo);
+ if (data != null && data.getStringExtra("sampleText") != null) {
+ sample = data.getStringExtra("sampleText");
+ }
+ Log.v(TAG, "Got sample text: " + sample);
+ if (mTts != null) {
+ mTts.speak(sample, TextToSpeech.QUEUE_FLUSH, null);
+ }
+ } else {
+ // TODO: Display an error here to the user.
+ Log.e(TAG, "Did not have a sample string for the requested language");
+ }
}
public boolean onPreferenceChange(Preference preference, Object objValue) {
if (KEY_TTS_USE_DEFAULT.equals(preference.getKey())) {
// "Use Defaults"
- int value = (Boolean)objValue ? 1 : 0;
- Settings.Secure.putInt(getContentResolver(), TTS_USE_DEFAULTS,
- value);
- Log.i(TAG, "TTS use default settings is "+objValue.toString());
+ int value = ((Boolean) objValue) ? 1 : 0;
+ Settings.Secure.putInt(getContentResolver(), TTS_USE_DEFAULTS, value);
+ Log.i(TAG, "TTS 'use default' settings changed, now " + value);
} else if (KEY_TTS_DEFAULT_RATE.equals(preference.getKey())) {
// Default rate
mDefaultRate = Integer.parseInt((String) objValue);
try {
- Settings.Secure.putInt(getContentResolver(),
- TTS_DEFAULT_RATE, mDefaultRate);
+ Settings.Secure.putInt(getContentResolver(), TTS_DEFAULT_RATE, mDefaultRate);
if (mTts != null) {
- mTts.setSpeechRate(mDefaultRate/100.0f);
+ mTts.setSpeechRate(mDefaultRate / 100.0f);
}
- Log.i(TAG, "TTS default rate is " + mDefaultRate);
+ Log.v(TAG, "TTS default rate changed, now " + mDefaultRate);
} catch (NumberFormatException e) {
Log.e(TAG, "could not persist default TTS rate setting", e);
}
@@ -522,19 +500,19 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
}
int newIndex = mDefaultLocPref.findIndexOfValue((String)objValue);
- Log.v("Settings", " selected is " + newIndex);
+ Log.v(TAG, " selected is " + newIndex);
mDemoStringIndex = newIndex > -1 ? newIndex : 0;
} else if (KEY_TTS_DEFAULT_SYNTH.equals(preference.getKey())) {
- mDefaultEng = objValue.toString();
- Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, mDefaultEng);
+ String defaultEng = objValue.toString();
+ Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, defaultEng);
if (mTts != null) {
- mTts.setEngineByPackageName(mDefaultEng);
+ mTts.setEngineByPackageName(defaultEng);
mEnableDemo = false;
mVoicesMissing = false;
updateWidgetState();
checkVoiceData();
}
- Log.v("Settings", "The default synth is: " + objValue.toString());
+ Log.v(TAG, "The default synth is: " + objValue.toString());
}
return true;
@@ -550,58 +528,44 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
// the actual speaking
getSampleText();
return true;
- }
- if (preference == mInstallData) {
+ } else if (preference == mInstallData) {
installVoiceData();
// quit this activity so it needs to be restarted after installation of the voice data
finish();
return true;
- }
- return false;
- }
-
- @Override
- public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
- if (Utils.isMonkeyRunning()) {
- return false;
- }
-
- if (preference instanceof CheckBoxPreference) {
+ } else if (preference.getKey().startsWith(KEY_PLUGIN_ENABLED_PREFIX)) {
final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
- if (!chkPref.getKey().equals(KEY_TTS_USE_DEFAULT)){
- if (chkPref.isChecked()) {
- chkPref.setChecked(false);
- AlertDialog d = (new AlertDialog.Builder(getActivity()))
- .setTitle(android.R.string.dialog_alert_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setMessage(
- getActivity().getString(R.string.tts_engine_security_warning,
- chkPref.getTitle()))
- .setCancelable(true)
- .setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- chkPref.setChecked(true);
- loadEngines();
- }
- })
- .setNegativeButton(android.R.string.cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- }
- })
- .create();
- d.show();
- } else {
- loadEngines();
- }
- return true;
+ if (chkPref.isChecked()) {
+ chkPref.setChecked(false);
+ AlertDialog d = (new AlertDialog.Builder(getActivity()))
+ .setTitle(android.R.string.dialog_alert_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(
+ getActivity().getString(R.string.tts_engine_security_warning,
+ chkPref.getTitle()))
+ .setCancelable(true)
+ .setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ chkPref.setChecked(true);
+ loadEngines();
+ }
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ })
+ .create();
+ d.show();
+ } else {
+ loadEngines();
}
+ return true;
}
return false;
}
-
private void updateWidgetState() {
mPlayExample.setEnabled(mEnableDemo);
mUseDefaultPref.setEnabled(mEnableDemo);
@@ -716,36 +680,23 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, DEFAULT_VARIANT_VAL);
}
-
private void loadEngines() {
- mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH);
-
- // TODO (clchen): Try to see if it is possible to be more efficient here
- // and not search for plugins again.
- Intent intent = new Intent("android.intent.action.START_TTS_ENGINE");
- ResolveInfo[] enginesArray = new ResolveInfo[0];
- PackageManager pm = getPackageManager();
- enginesArray = pm.queryIntentActivities(intent, 0).toArray(enginesArray);
+ List<TextToSpeech.EngineInfo> engines = mTts.getEngines();
ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
ArrayList<CharSequence> values = new ArrayList<CharSequence>();
- String enabledEngines = "";
- for (int i = 0; i < enginesArray.length; i++) {
- String pluginPackageName = enginesArray[i].activityInfo.packageName;
- if (pluginPackageName.equals(SYSTEM_TTS)) {
- entries.add(enginesArray[i].loadLabel(pm));
- values.add(pluginPackageName);
- } else {
- CheckBoxPreference pref = (CheckBoxPreference) findPreference(
- KEY_PLUGIN_ENABLED_PREFIX + pluginPackageName);
- if ((pref != null) && pref.isChecked()){
- entries.add(enginesArray[i].loadLabel(pm));
- values.add(pluginPackageName);
- enabledEngines = enabledEngines + pluginPackageName + " ";
- }
+ StringBuilder enabledEngines = new StringBuilder();
+
+ for (TextToSpeech.EngineInfo engine : engines) {
+ Log.v(TAG, "Engine: " + engine);
+ if (isEngineEnabled(engine.name)) {
+ entries.add(engine.label);
+ values.add(engine.name);
+ if (enabledEngines.length() > 0) enabledEngines.append(' ');
+ enabledEngines.append(engine.name);
}
}
ContentResolver resolver = getContentResolver();
- Settings.Secure.putString(resolver, TTS_ENABLED_PLUGINS, enabledEngines);
+ Settings.Secure.putString(resolver, TTS_ENABLED_PLUGINS, enabledEngines.toString());
CharSequence entriesArray[] = new CharSequence[entries.size()];
CharSequence valuesArray[] = new CharSequence[values.size()];
@@ -757,9 +708,18 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
String selectedEngine = Settings.Secure.getString(getContentResolver(), TTS_DEFAULT_SYNTH);
int selectedEngineIndex = mDefaultSynthPref.findIndexOfValue(selectedEngine);
if (selectedEngineIndex == -1){
- selectedEngineIndex = mDefaultSynthPref.findIndexOfValue(SYSTEM_TTS);
+ selectedEngineIndex =
+ mDefaultSynthPref.findIndexOfValue(TextToSpeech.Engine.DEFAULT_ENGINE);
}
- mDefaultSynthPref.setValueIndex(selectedEngineIndex);
+ if (selectedEngineIndex >= 0) {
+ mDefaultSynthPref.setValueIndex(selectedEngineIndex);
+ }
+ }
+
+ private boolean isEngineEnabled(String engineName) {
+ if (engineName.equals(TextToSpeech.Engine.DEFAULT_ENGINE)) return true;
+ String enginePref = KEY_PLUGIN_ENABLED_PREFIX + engineName;
+ return getPreferenceManager().getSharedPreferences().getBoolean(enginePref, false);
}
}
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
index b13126a..22112d7 100644
--- a/src/com/android/settings/UserDictionarySettings.java
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -46,6 +46,7 @@ import android.widget.TextView;
import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
+import java.util.Arrays;
import java.util.Locale;
public class UserDictionarySettings extends ListFragment implements DialogCreatable {
@@ -63,23 +64,29 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata
// Either the locale is empty (means the word is applicable to all locales)
// or the word equals our current locale
- private static final String QUERY_SELECTION = UserDictionary.Words.LOCALE + "=? OR "
- + UserDictionary.Words.LOCALE + " is null";
+ private static final String QUERY_SELECTION =
+ UserDictionary.Words.LOCALE + "=?";
+ private static final String QUERY_SELECTION_ALL_LOCALES =
+ UserDictionary.Words.LOCALE + " is null";
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 View mView;
private Cursor mCursor;
-
+
+ protected String mLocale;
+
private boolean mAddedWordAlready;
private boolean mAutoReturn;
@@ -101,7 +108,25 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mCursor = createCursor();
+ final Intent intent = getActivity().getIntent();
+ final String localeFromIntent =
+ null == intent ? null : intent.getStringExtra("locale");
+
+ final Bundle arguments = getArguments();
+ final String localeFromArguments =
+ null == arguments ? null : arguments.getString("locale");
+
+ final String locale;
+ if (null != localeFromArguments) {
+ locale = localeFromArguments;
+ } else if (null != localeFromIntent) {
+ locale = localeFromIntent;
+ } else {
+ locale = null;
+ }
+
+ mLocale = locale;
+ mCursor = createCursor(locale);
TextView emptyView = (TextView)mView.findViewById(R.id.empty);
emptyView.setText(R.string.user_dict_settings_empty_text);
@@ -117,12 +142,12 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata
mAddedWordAlready = savedInstanceState.getBoolean(INSTANCE_KEY_ADDED_WORD, false);
}
}
-
+
@Override
public void onResume() {
super.onResume();
final Intent intent = getActivity().getIntent();
- if (!mAddedWordAlready
+ if (!mAddedWordAlready
&& intent.getAction().equals("com.android.settings.USER_DICTIONARY_INSERT")) {
final String word = intent.getStringExtra(EXTRA_WORD);
mAutoReturn = true;
@@ -139,12 +164,28 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata
outState.putBoolean(INSTANCE_KEY_ADDED_WORD, mAddedWordAlready);
}
- private Cursor createCursor() {
- String currentLocale = Locale.getDefault().toString();
- // Case-insensitive sort
- return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
- QUERY_SELECTION, new String[] { currentLocale },
- "UPPER(" + UserDictionary.Words.WORD + ")");
+ private Cursor createCursor(final String locale) {
+ // Locale can be any of:
+ // - The string representation of a locale, as returned by Locale#toString()
+ // - The empty string. This means we want a cursor returning words valid for all locales.
+ // - null. This means we want a cursor for the current locale, whatever this is.
+ // Note that this contrasts with the data inside the database, where NULL means "all
+ // locales" and there should never be an empty string. The confusion is called by the
+ // historical use of null for "all locales".
+ // TODO: it should be easy to make this more readable by making the special values
+ // human-readable, like "all_locales" and "current_locales" strings, provided they
+ // can be guaranteed not to match locales that may exist.
+ if ("".equals(locale)) {
+ // Case-insensitive sort
+ return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
+ QUERY_SELECTION_ALL_LOCALES, null,
+ "UPPER(" + UserDictionary.Words.WORD + ")");
+ } else {
+ final String queryLocale = null != locale ? locale : Locale.getDefault().toString();
+ return getActivity().managedQuery(UserDictionary.Words.CONTENT_URI, QUERY_PROJECTION,
+ QUERY_SELECTION, new String[] { queryLocale },
+ "UPPER(" + UserDictionary.Words.WORD + ")");
+ }
}
private ListAdapter createAdapter() {
@@ -153,7 +194,7 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata
new String[] { UserDictionary.Words.WORD, UserDictionary.Words._ID },
new int[] { android.R.id.text1, R.id.delete_button }, this);
}
-
+
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String word = getWord(position);
@@ -235,13 +276,28 @@ public class UserDictionarySettings extends ListFragment implements DialogCreata
// 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.
- UserDictionary.Words.addWord(getActivity(), word.toString(),
- 250, UserDictionary.Words.LOCALE_TYPE_ALL);
+ 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 (!mCursor.requery()) {
throw new IllegalStateException("can't requery on already-closed cursor.");
}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 18c6159..422ae90 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -36,8 +36,10 @@ import android.telephony.TelephonyManager;
import android.text.TextUtils;
import java.net.InetAddress;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
public class Utils {
@@ -308,4 +310,24 @@ public class Utils {
}
return addresses;
}
+
+ public static Locale createLocaleFromString(String localeStr) {
+ // TODO: is there a better way to actually construct a locale that will match?
+ // The main problem is, on top of Java specs, locale.toString() and
+ // new Locale(locale.toString()).toString() do not return equal() strings in
+ // many cases, because the constructor takes the only string as the language
+ // code. So : new Locale("en", "US").toString() => "en_US"
+ // And : new Locale("en_US").toString() => "en_us"
+ if (null == localeStr)
+ return Locale.getDefault();
+ String[] brokenDownLocale = localeStr.split("_", 3);
+ // split may not return a 0-length array.
+ if (1 == brokenDownLocale.length) {
+ return new Locale(brokenDownLocale[0]);
+ } else if (2 == brokenDownLocale.length) {
+ return new Locale(brokenDownLocale[0], brokenDownLocale[1]);
+ } else {
+ return new Locale(brokenDownLocale[0], brokenDownLocale[1], brokenDownLocale[2]);
+ }
+ }
}
diff --git a/src/com/android/settings/accounts/AccountPreferenceBase.java b/src/com/android/settings/accounts/AccountPreferenceBase.java
index a84bece..a0d6a7f 100644
--- a/src/com/android/settings/accounts/AccountPreferenceBase.java
+++ b/src/com/android/settings/accounts/AccountPreferenceBase.java
@@ -32,6 +32,7 @@ import android.content.Context;
import android.content.SyncAdapterType;
import android.content.SyncStatusObserver;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -113,7 +114,7 @@ class AccountPreferenceBase extends SettingsPreferenceFragment
mAccountTypeToAuthorities.put(sa.accountType, authorities);
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.d(TAG, "added authority " + sa.authority + " to accountType "
+ Log.d(TAG, "added authority " + sa.authority + " to accountType "
+ sa.accountType);
}
authorities.add(sa.authority);
@@ -136,7 +137,10 @@ class AccountPreferenceBase extends SettingsPreferenceFragment
icon = authContext.getResources().getDrawable(desc.iconId);
} catch (PackageManager.NameNotFoundException e) {
// TODO: place holder icon for missing account icons?
- Log.w(TAG, "No icon for account type " + accountType);
+ Log.w(TAG, "No icon name for account type " + accountType);
+ } catch (Resources.NotFoundException e) {
+ // TODO: place holder icon for missing account icons?
+ Log.w(TAG, "No icon resource for account type " + accountType);
}
}
return icon;
@@ -155,7 +159,9 @@ class AccountPreferenceBase extends SettingsPreferenceFragment
Context authContext = getActivity().createPackageContext(desc.packageName, 0);
label = authContext.getResources().getText(desc.labelId);
} catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "No label for account type " + ", type " + accountType);
+ Log.w(TAG, "No label name for account type " + accountType);
+ } catch (Resources.NotFoundException e) {
+ Log.w(TAG, "No label icon for account type " + accountType);
}
}
return label;
@@ -179,6 +185,8 @@ class AccountPreferenceBase extends SettingsPreferenceFragment
}
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
+ } catch (Resources.NotFoundException e) {
+ Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
}
}
return prefs;
diff --git a/src/com/android/settings/accounts/ChooseAccountActivity.java b/src/com/android/settings/accounts/ChooseAccountActivity.java
index 9576dee..631fe47 100644
--- a/src/com/android/settings/accounts/ChooseAccountActivity.java
+++ b/src/com/android/settings/accounts/ChooseAccountActivity.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SyncAdapterType;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.Preference;
@@ -199,7 +200,10 @@ public class ChooseAccountActivity extends PreferenceActivity {
icon = authContext.getResources().getDrawable(desc.iconId);
} catch (PackageManager.NameNotFoundException e) {
// TODO: place holder icon for missing account icons?
- Log.w(TAG, "No icon for account type " + accountType);
+ Log.w(TAG, "No icon name for account type " + accountType);
+ } catch (Resources.NotFoundException e) {
+ // TODO: place holder icon for missing account icons?
+ Log.w(TAG, "No icon resource for account type " + accountType);
}
}
return icon;
@@ -218,7 +222,9 @@ public class ChooseAccountActivity extends PreferenceActivity {
Context authContext = createPackageContext(desc.packageName, 0);
label = authContext.getResources().getText(desc.labelId);
} catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "No label for account type " + ", type " + accountType);
+ Log.w(TAG, "No label name for account type " + accountType);
+ } catch (Resources.NotFoundException e) {
+ Log.w(TAG, "No label resource for account type " + accountType);
}
}
return label;
diff --git a/src/com/android/settings/deviceinfo/PercentageBarChart.java b/src/com/android/settings/deviceinfo/PercentageBarChart.java
index 0c71c12..95973c4 100644
--- a/src/com/android/settings/deviceinfo/PercentageBarChart.java
+++ b/src/com/android/settings/deviceinfo/PercentageBarChart.java
@@ -71,20 +71,21 @@ public class PercentageBarChart extends View {
final int width = right - left;
- int lastX = left;
+ float lastX = left;
if (mEntries != null) {
for (final Entry e : mEntries) {
- final int entryWidth;
- if (e.percentage == 0f) {
- entryWidth = 0;
+ final float entryWidth;
+ if (e.percentage == 0.0f) {
+ entryWidth = 0.0f;
} else {
- entryWidth = Math.max(mMinTickWidth, (int) (width * e.percentage));
+ entryWidth = Math.max(mMinTickWidth, width * e.percentage);
}
- final int nextX = lastX + entryWidth;
- if (nextX >= right) {
- break;
+ final float nextX = lastX + entryWidth;
+ if (nextX > right) {
+ canvas.drawRect(lastX, top, right, bottom, e.paint);
+ return;
}
canvas.drawRect(lastX, top, nextX, bottom, e.paint);
@@ -92,7 +93,7 @@ public class PercentageBarChart extends View {
}
}
- canvas.drawRect(lastX, top, lastX + width, bottom, mEmptyPaint);
+ canvas.drawRect(lastX, top, right, bottom, mEmptyPaint);
}
/**
diff --git a/src/com/android/settings/deviceinfo/StorageMeasurement.java b/src/com/android/settings/deviceinfo/StorageMeasurement.java
index 14b5108..6d49ebf 100644
--- a/src/com/android/settings/deviceinfo/StorageMeasurement.java
+++ b/src/com/android/settings/deviceinfo/StorageMeasurement.java
@@ -478,6 +478,7 @@ public class StorageMeasurement {
File top = new File(mStorageVolume.getPath());
mFileInfoForMisc = new ArrayList<FileInfo>();
File[] files = top.listFiles();
+ if (files == null) return;
final int len = files.length;
// Get sizes of all top level nodes except the ones already computed...
long counter = 0;
diff --git a/src/com/android/settings/deviceinfo/UsageBarPreference.java b/src/com/android/settings/deviceinfo/UsageBarPreference.java
index e9909f1..5aeaef5 100644
--- a/src/com/android/settings/deviceinfo/UsageBarPreference.java
+++ b/src/com/android/settings/deviceinfo/UsageBarPreference.java
@@ -36,17 +36,17 @@ public class UsageBarPreference extends Preference {
public UsageBarPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- setWidgetLayoutResource(R.layout.preference_memoryusage);
+ setLayoutResource(R.layout.preference_memoryusage);
}
public UsageBarPreference(Context context) {
super(context);
- setWidgetLayoutResource(R.layout.preference_memoryusage);
+ setLayoutResource(R.layout.preference_memoryusage);
}
public UsageBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- setWidgetLayoutResource(R.layout.preference_memoryusage);
+ setLayoutResource(R.layout.preference_memoryusage);
}
public void addEntry(float percentage, int color) {
diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java
index 97ebf43..13a962d 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java
@@ -368,9 +368,9 @@ public class BatteryHistoryChart extends View {
}
if (rec.batteryLevel != lastLevel || pos == 1) {
lastLevel = rec.batteryLevel;
- lastInteresting = pos;
- mHistEnd = rec.time;
}
+ lastInteresting = pos;
+ mHistEnd = rec.time;
aggrStates |= rec.states;
}
}
@@ -438,7 +438,13 @@ public class BatteryHistoryChart extends View {
2, getResources().getDisplayMetrics());
if (h > (textHeight*6)) {
mLargeMode = true;
- mLineWidth = textHeight/2;
+ if (h > (textHeight*15)) {
+ // Plenty of room for the chart.
+ mLineWidth = textHeight/2;
+ } else {
+ // Compress lines to make more room for chart.
+ mLineWidth = textHeight/3;
+ }
mLevelTop = textHeight + mLineWidth;
mScreenOnPaint.setARGB(255, 32, 64, 255);
mGpsOnPaint.setARGB(255, 32, 64, 255);
@@ -472,7 +478,8 @@ public class BatteryHistoryChart extends View {
mWifiRunningOffset = mWakeLockOffset + barOffset;
mGpsOnOffset = mWifiRunningOffset + (mHaveWifi ? barOffset : 0);
mPhoneSignalOffset = mGpsOnOffset + (mHaveGps ? barOffset : 0);
- mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? barOffset : 0) + mLineWidth;
+ mLevelOffset = mPhoneSignalOffset + (mHavePhoneSignal ? barOffset : 0)
+ + ((mLineWidth*3)/2);
if (mHavePhoneSignal) {
mPhoneSignalChart.init(w);
}
@@ -670,8 +677,8 @@ public class BatteryHistoryChart extends View {
if (!mBatCriticalPath.isEmpty()) {
canvas.drawPath(mBatCriticalPath, mBatteryCriticalPaint);
}
- int top = height - (mHavePhoneSignal ? mPhoneSignalOffset - (mLineWidth/2) : 0);
if (mHavePhoneSignal) {
+ int top = height-mPhoneSignalOffset - (mLineWidth/2);
mPhoneSignalChart.draw(canvas, top, mLineWidth);
}
if (!mScreenOnPath.isEmpty()) {
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index a4808b0..c72f0ba 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -18,9 +18,11 @@ package com.android.settings.inputmethod;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.UserDictionarySettings;
import com.android.settings.Utils;
import com.android.settings.VoiceInputOutputSettings;
+import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -30,12 +32,17 @@ import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.view.inputmethod.InputMethodManager;
+import java.util.Set;
+
public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
implements Preference.OnPreferenceChangeListener{
private static final String KEY_PHONE_LANGUAGE = "phone_language";
private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method";
private static final String KEY_INPUT_METHOD_SELECTOR = "input_method_selector";
+ private static final String KEY_LANGUAGE_SETTINGS_CATEGORY = "language_settings_category";
+ private static final String KEY_USER_DICTIONARY_SETTINGS = "key_user_dictionary_settings";
+
private int mDefaultInputMethodSelectorVisibility = 0;
private ListPreference mShowInputMethodSelectorPref;
@@ -77,6 +84,28 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
}
}
+ private void updateUserDictionaryPreference(Preference userDictionaryPreference) {
+ final Activity activity = getActivity();
+ final Set<String> localeList = UserDictionaryList.getUserDictionaryLocalesList(activity);
+ if (localeList.size() <= 1) {
+ userDictionaryPreference.setTitle(R.string.user_dict_single_settings_title);
+ userDictionaryPreference.setFragment(UserDictionarySettings.class.getName());
+ // If the size of localeList is 0, we don't set the locale parameter in the
+ // extras. This will be interpreted by the UserDictionarySettings class as
+ // meaning "the current locale".
+ // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesList()
+ // the locale list always has at least one element, since it always includes the current
+ // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesList().
+ if (localeList.size() == 1) {
+ final String locale = (String)localeList.toArray()[0];
+ userDictionaryPreference.getExtras().putString("locale", locale);
+ }
+ } else {
+ userDictionaryPreference.setTitle(R.string.user_dict_multiple_settings_title);
+ userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
+ }
+ }
+
@Override
public void onResume() {
super.onResume();
@@ -89,6 +118,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
}
}
+ updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
mShowInputMethodSelectorPref.setOnPreferenceChangeListener(this);
}
diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java
new file mode 100644
index 0000000..5db2841
--- /dev/null
+++ b/src/com/android/settings/inputmethod/UserDictionaryList.java
@@ -0,0 +1,109 @@
+/*
+ * 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.SettingsPreferenceFragment;
+import com.android.settings.UserDictionarySettings;
+import com.android.settings.Utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceGroup;
+import android.provider.UserDictionary;
+
+import java.util.Locale;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class UserDictionaryList extends SettingsPreferenceFragment {
+
+ private static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION =
+ "android.settings.USER_DICTIONARY_SETTINGS";
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
+ }
+
+ static Set<String> getUserDictionaryLocalesList(Activity activity) {
+ final Cursor cursor = activity.managedQuery(UserDictionary.Words.CONTENT_URI,
+ new String[] { UserDictionary.Words.LOCALE },
+ null, null, null);
+ final Set<String> localeList = new TreeSet<String>();
+ if (cursor.moveToFirst()) {
+ final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
+ do {
+ String locale = cursor.getString(columnIndex);
+ localeList.add(null != locale ? locale : "");
+ } while (cursor.moveToNext());
+ }
+ localeList.add(Locale.getDefault().toString());
+ return localeList;
+ }
+
+ /**
+ * Creates the entries that allow the user to go into the user dictionary for each locale.
+ * @param userDictGroup The group to put the settings in.
+ */
+ protected void createUserDictSettings(PreferenceGroup userDictGroup) {
+ final Activity activity = getActivity();
+ userDictGroup.removeAll();
+ final Set<String> localeList = UserDictionaryList.getUserDictionaryLocalesList(activity);
+
+ if (localeList.isEmpty()) {
+ userDictGroup.addPreference(createUserDictionaryPreference(null, activity));
+ } else {
+ for (String locale : localeList) {
+ userDictGroup.addPreference(createUserDictionaryPreference(locale, activity));
+ }
+ }
+ }
+
+ /**
+ * Create a single User Dictionary Preference object, with its parameters set.
+ * @param locale The locale for which this user dictionary is for.
+ * @return The corresponding preference.
+ */
+ protected Preference createUserDictionaryPreference(String locale, Activity activity) {
+ final Preference newPref = new Preference(getActivity());
+ final Intent intent = new Intent(USER_DICTIONARY_SETTINGS_INTENT_ACTION);
+ if (null == locale) {
+ newPref.setTitle(Locale.getDefault().getDisplayName());
+ } else {
+ if ("".equals(locale))
+ newPref.setTitle(getString(R.string.user_dict_settings_all_languages));
+ else
+ newPref.setTitle(Utils.createLocaleFromString(locale).getDisplayName());
+ intent.putExtra("locale", locale);
+ newPref.getExtras().putString("locale", locale);
+ }
+ newPref.setIntent(intent);
+ newPref.setFragment(UserDictionarySettings.class.getName());
+ return newPref;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ createUserDictSettings(getPreferenceScreen());
+ }
+}
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index 5d75b6a..9b96761 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -55,6 +55,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.nio.charset.Charsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -698,7 +699,7 @@ public class VpnSettings extends SettingsPreferenceFragment
}
private boolean isKeyStoreUnlocked() {
- return mKeyStore.test() == KeyStore.NO_ERROR;
+ return mKeyStore.state() == KeyStore.State.UNLOCKED;
}
// Returns true if the profile needs to access keystore
@@ -1034,7 +1035,7 @@ public class VpnSettings extends SettingsPreferenceFragment
String presharedKey = pskProfile.getPresharedKey();
String key = KEY_PREFIX_IPSEC_PSK + p.getId();
if (!TextUtils.isEmpty(presharedKey) &&
- !mKeyStore.put(key, presharedKey)) {
+ !mKeyStore.put(key, presharedKey.getBytes(Charsets.UTF_8))) {
Log.e(TAG, "keystore write failed: key=" + key);
}
pskProfile.setPresharedKey(key);
@@ -1046,7 +1047,7 @@ public class VpnSettings extends SettingsPreferenceFragment
if (l2tpProfile.isSecretEnabled()) {
String secret = l2tpProfile.getSecretString();
if (!TextUtils.isEmpty(secret) &&
- !mKeyStore.put(key, secret)) {
+ !mKeyStore.put(key, secret.getBytes(Charsets.UTF_8))) {
Log.e(TAG, "keystore write failed: key=" + key);
}
l2tpProfile.setSecretString(key);
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 7e07162..993633f 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -245,7 +245,7 @@ public class WifiSettings extends SettingsPreferenceFragment
getActivity().registerReceiver(mReceiver, mFilter);
if (mKeyStoreNetworkId != INVALID_NETWORK_ID &&
- KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
+ KeyStore.getInstance().state() == KeyStore.State.UNLOCKED) {
mWifiManager.connectNetwork(mKeyStoreNetworkId);
}
mKeyStoreNetworkId = INVALID_NETWORK_ID;
@@ -417,7 +417,7 @@ public class WifiSettings extends SettingsPreferenceFragment
private boolean requireKeyStore(WifiConfiguration config) {
if (WifiConfigController.requireKeyStore(config) &&
- KeyStore.getInstance().test() != KeyStore.NO_ERROR) {
+ KeyStore.getInstance().state() != KeyStore.State.UNLOCKED) {
mKeyStoreNetworkId = config.networkId;
Credentials.getInstance().unlock(getActivity());
return true;
diff --git a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
index b265362..c9bc758 100644
--- a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
+++ b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
@@ -70,12 +70,6 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
sNetworkStateMap.put(DetailedState.FAILED, DetailedState.FAILED);
}
- /**
- * Used with {@link Button#setTag(Object)} to remember "Connect" button is pressed in
- * with "add network" flow.
- */
- private static final int CONNECT_BUTTON_TAG_ADD_NETWORK = 1;
-
private WifiSettings mWifiSettings;
private WifiManager mWifiManager;
@@ -161,7 +155,7 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
// At first, Wifi module doesn't return SCANNING state (it's too early), so we manually
// show it.
- showScanningProgressBar();
+ showScanningState();
}
private void initViews() {
@@ -278,17 +272,16 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
switch (state) {
case SCANNING: {
- // Let users know the device is working correctly though currently there's
- // no visible network on the list.
- if (mWifiSettings.getAccessPointsCount() == 0) {
- showScanningState();
- } else {
- // Users already see available networks.
- showDisconnectedProgressBar();
- if (mScreenState == SCREEN_STATE_DISCONNECTED) {
+ if (mScreenState == SCREEN_STATE_DISCONNECTED) {
+ if (mWifiSettings.getAccessPointsCount() == 0) {
+ showScanningState();
+ } else {
+ showDisconnectedProgressBar();
mWifiSettingsFragmentLayout.setVisibility(View.VISIBLE);
mBottomPadding.setVisibility(View.GONE);
}
+ } else {
+ showDisconnectedProgressBar();
}
break;
}
@@ -303,7 +296,8 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
break;
}
default: // DISCONNECTED, FAILED
- if (mScreenState != SCREEN_STATE_CONNECTED) {
+ if (mScreenState != SCREEN_STATE_CONNECTED &&
+ mWifiSettings.getAccessPointsCount() > 0) {
showDisconnectedState(Summary.get(this, state));
}
break;
@@ -313,7 +307,8 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
private void showDisconnectedState(String stateString) {
showDisconnectedProgressBar();
- if (mScreenState == SCREEN_STATE_DISCONNECTED) {
+ if (mScreenState == SCREEN_STATE_DISCONNECTED &&
+ mWifiSettings.getAccessPointsCount() > 0) {
mWifiSettingsFragmentLayout.setVisibility(View.VISIBLE);
mBottomPadding.setVisibility(View.GONE);
}
@@ -461,13 +456,11 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
parent.removeAllViews();
mWifiConfig = new WifiConfigUiForSetupWizardXL(this, parent, selectedAccessPoint, edit);
- // Tag will be updated in this method when needed.
- mConnectButton.setTag(null);
if (selectedAccessPoint == null) { // "Add network" flow
showAddNetworkTitle();
mConnectButton.setVisibility(View.VISIBLE);
- mConnectButton.setTag(CONNECT_BUTTON_TAG_ADD_NETWORK);
+ showDisconnectedProgressBar();
showEditingButtonState();
} else if (selectedAccessPoint.security == AccessPoint.SECURITY_NONE) {
mNetworkName = selectedAccessPoint.getTitle().toString();
@@ -477,6 +470,7 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
} else {
mNetworkName = selectedAccessPoint.getTitle().toString();
showEditingTitle();
+ showDisconnectedProgressBar();
showEditingButtonState();
if (selectedAccessPoint.security == AccessPoint.SECURITY_EAP) {
onEapNetworkSelected();
@@ -632,8 +626,9 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
mAddNetworkButton.setEnabled(true);
mRefreshButton.setEnabled(true);
mSkipOrNextButton.setEnabled(true);
- mWifiSettingsFragmentLayout.setVisibility(View.VISIBLE);
showDisconnectedProgressBar();
+ mWifiSettingsFragmentLayout.setVisibility(View.VISIBLE);
+ mBottomPadding.setVisibility(View.GONE);
}
setPaddingVisibility(View.VISIBLE);
@@ -680,15 +675,7 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
}
private void refreshAccessPoints(boolean disconnectNetwork) {
- final Object tag = mConnectButton.getTag();
- if (tag != null && (tag instanceof Integer) &&
- ((Integer)tag == CONNECT_BUTTON_TAG_ADD_NETWORK)) {
- // In "Add network" flow, we won't get DetaledState available for changing ProgressBar
- // state. Instead we manually show previous status here.
- showDisconnectedState(Summary.get(this, mPreviousNetworkState));
- } else {
- showScanningState();
- }
+ showScanningState();
if (disconnectNetwork) {
mWifiManager.disconnect();