Merge "b/2608693 Fix the problem where BT was automatically reconnecting ... after the user unpaired while docked." into froyo
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 0ae8eb4..f16f8c9 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -388,14 +388,16 @@
     <!-- New incoming call vibrate options. -->
     <string-array name="vibrate_entries">
         <item>Always</item>
-        <item>Only when silent</item>
         <item>Never</item>
+        <item>Only in Silent mode</item>
+        <item>Only when not in Silent mode</item>
     </string-array>
 
-    <!-- Corresponds to AudioManager.VIBRATE_SETTING_*. Do not translate. -->
+    <!-- Values for vibrate_entries matching constants in SoundSettings. Do not translate. -->
     <string-array name="vibrate_values" translatable="false">
-        <item>1</item>
-        <item>2</item>
-        <item>0</item>
+        <item>always</item>
+        <item>never</item>
+        <item>silent</item>
+        <item>notsilent</item>
     </string-array>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 871036b..a0d3b41 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1019,9 +1019,9 @@
     <!-- Sound settings screen, setting option summary text -->
     <string name="vibrate_in_silent_summary">Allow vibration feedback in silent mode</string>
     <!-- Sound settings screen, setting option name checkbox -->
-    <string name="vibrate_title">Phone vibrate</string>
+    <string name="vibrate_title">Vibrate</string>
     <!-- Sound settings screen, setting option summary text -->
-    <string name="vibrate_summary">Vibrate phone for incoming calls</string>
+    <string name="vibrate_summary">Vibration feedback for calls and notifications</string>
     <!-- Sound settings screen, setting option name -->
     <string name="notification_sound_title">Notification ringtone</string>
     <!-- Sound settings screen, setting option summary text -->
@@ -2521,4 +2521,9 @@
 
     <!-- Name to assign to a Network Access Point that was saved without a name -->
     <string name="untitled_apn">Untitled</string>
+
+    <string name="sound_category_sound_title">General</string>
+    <string name="sound_category_calls_title">Incoming calls</string>
+    <string name="sound_category_notification_title">Notifications</string>
+    <string name="sound_category_feedback_title">Feedback</string>
 </resources>
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index bcb49ec..1091b90 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -19,6 +19,10 @@
         android:key="sound_settings"
         xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
 
+    <PreferenceCategory
+            android:title="@string/sound_category_sound_title"
+            >
+
         <CheckBoxPreference
                 android:key="silent"
                 android:title="@string/silent_mode_title"
@@ -27,12 +31,13 @@
                 android:order="1"
                 android:disableDependentsState="true" />
 
-        <CheckBoxPreference
-                android:key="vibrate_in_silent"
-                android:title="@string/vibrate_in_silent_title"
-                android:summary="@string/vibrate_in_silent_summary"
-                android:order="2"
-                android:persistent="false" />
+        <ListPreference
+                android:key="vibrate"
+                android:order="6"
+                android:title="@string/vibrate_title"
+                android:summary="@string/vibrate_summary"
+                android:entries="@array/vibrate_entries"
+                android:entryValues="@array/vibrate_values" />
 
         <com.android.settings.RingerVolumePreference
                 android:key="ring_volume"
@@ -44,6 +49,12 @@
                 android:order="3"
                 android:streamType="ring" />
 
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/sound_category_calls_title"
+            >
+
         <com.android.settings.DefaultRingtonePreference
                 android:key="ringtone"
                 android:title="@string/ringtone_title"
@@ -53,13 +64,11 @@
                 android:order="5"
                 android:ringtoneType="ringtone" />
 
-        <ListPreference
-                android:key="vibrate"
-                android:order="6"
-                android:title="@string/vibrate_title"
-                android:summary="@string/vibrate_summary"
-                android:entries="@array/vibrate_entries"
-                android:entryValues="@array/vibrate_values" />
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/sound_category_notification_title"
+            >
 
         <com.android.settings.DefaultRingtonePreference
                 android:key="notification_sound"
@@ -77,6 +86,12 @@
                 android:order="8"
                 android:persistent="false" />
 
+    </PreferenceCategory>
+
+    <PreferenceCategory
+            android:title="@string/sound_category_feedback_title"
+            >
+
         <CheckBoxPreference
                 android:key="dtmf_tone"
                 android:title="@string/dtmf_tone_enable_title"
@@ -116,4 +131,6 @@
                 android:entries="@array/emergency_tone_entries"
                 android:entryValues="@array/emergency_tone_values" />
 
+    </PreferenceCategory>
+
 </PreferenceScreen>
diff --git a/src/com/android/settings/InstalledAppDetails.java b/src/com/android/settings/InstalledAppDetails.java
index a8ceab0..e050dc5 100644
--- a/src/com/android/settings/InstalledAppDetails.java
+++ b/src/com/android/settings/InstalledAppDetails.java
@@ -242,7 +242,8 @@
             if ((mAppInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) == 0 &&
                     (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 &&
                     pkgInfo != null) {
-                if (pkgInfo.installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
+                if (pkgInfo.installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL ||
+                        pkgInfo.installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
                     moveDisable = false;
                 } else if (pkgInfo.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED) {
                     IPackageManager ipm  = IPackageManager.Stub.asInterface(
@@ -275,11 +276,12 @@
         boolean enabled = true;
         if (mUpdatedSysApp) {
             mUninstallButton.setText(R.string.app_factory_reset);
-        } else if ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0){
-            mUninstallButton.setText(R.string.uninstall_text);
         } else {
-            // Disable uninstall for system apps
-            enabled = false;
+            if ((mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0){
+                // Disable button for system applications.
+                enabled = false;
+            }
+            mUninstallButton.setText(R.string.uninstall_text);
         }
         mUninstallButton.setEnabled(enabled);
         if (enabled) {
diff --git a/src/com/android/settings/SoundSettings.java b/src/com/android/settings/SoundSettings.java
index ca7a1f3..bfb5566 100644
--- a/src/com/android/settings/SoundSettings.java
+++ b/src/com/android/settings/SoundSettings.java
@@ -49,7 +49,6 @@
 
     private static final String KEY_SILENT = "silent";
     private static final String KEY_VIBRATE = "vibrate";
-    private static final String KEY_VIBRATE_IN_SILENT = "vibrate_in_silent";
     private static final String KEY_DTMF_TONE = "dtmf_tone";
     private static final String KEY_SOUND_EFFECTS = "sound_effects";
     private static final String KEY_HAPTIC_FEEDBACK = "haptic_feedback";
@@ -58,6 +57,11 @@
     private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
     private static final String KEY_LOCK_SOUNDS = "lock_sounds";
 
+    private static final String VALUE_VIBRATE_NEVER = "never";
+    private static final String VALUE_VIBRATE_ALWAYS = "always";
+    private static final String VALUE_VIBRATE_ONLY_SILENT = "silent";
+    private static final String VALUE_VIBRATE_UNLESS_SILENT = "notsilent";
+
     private CheckBoxPreference mSilent;
 
     /*
@@ -67,8 +71,7 @@
      * Otherwise, it will adjust the normal ringer mode's ring or ring+vibrate
      * setting.
      */
-    private ListPreference mPhoneVibrate;
-    private CheckBoxPreference mVibrateInSilent;
+    private ListPreference mVibrate;
     private CheckBoxPreference mDtmfTone;
     private CheckBoxPreference mSoundEffects;
     private CheckBoxPreference mHapticFeedback;
@@ -105,10 +108,9 @@
 
         mSilent = (CheckBoxPreference) findPreference(KEY_SILENT);
 
-        mPhoneVibrate = (ListPreference) findPreference(KEY_VIBRATE);
-        mPhoneVibrate.setOnPreferenceChangeListener(this);
+        mVibrate = (ListPreference) findPreference(KEY_VIBRATE);
+        mVibrate.setOnPreferenceChangeListener(this);
 
-        mVibrateInSilent = (CheckBoxPreference) findPreference(KEY_VIBRATE_IN_SILENT);
         mDtmfTone = (CheckBoxPreference) findPreference(KEY_DTMF_TONE);
         mDtmfTone.setPersistent(false);
         mDtmfTone.setChecked(Settings.System.getInt(resolver,
@@ -169,6 +171,78 @@
         unregisterReceiver(mReceiver);
     }
 
+    private String getPhoneVibrateSettingValue() {
+        boolean vibeInSilent = (Settings.System.getInt(
+            getContentResolver(),
+            Settings.System.VIBRATE_IN_SILENT,
+            1) == 1);
+
+        // Control phone vibe independent of silent mode
+        int callsVibrateSetting = 
+            mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
+
+        if (vibeInSilent) {
+            if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_OFF) {
+                // this state does not make sense; fix it up for the user
+                mAudioManager.setVibrateSetting(
+                    AudioManager.VIBRATE_TYPE_RINGER,
+                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+            }
+            if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ON) {
+                return VALUE_VIBRATE_ALWAYS;
+            } else {
+                return VALUE_VIBRATE_ONLY_SILENT;
+            }
+        } else {
+            if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ONLY_SILENT) {
+                // this state does not make sense; fix it up
+                mAudioManager.setVibrateSetting(
+                    AudioManager.VIBRATE_TYPE_RINGER,
+                    AudioManager.VIBRATE_SETTING_OFF);
+            }
+            if (callsVibrateSetting == AudioManager.VIBRATE_SETTING_ON) {
+                return VALUE_VIBRATE_UNLESS_SILENT;
+            } else {
+                return VALUE_VIBRATE_NEVER;
+            }
+        }
+    }
+
+    private void setPhoneVibrateSettingValue(String value) {
+        boolean vibeInSilent;
+        int callsVibrateSetting;
+
+        if (value.equals(VALUE_VIBRATE_UNLESS_SILENT)) {
+            callsVibrateSetting = AudioManager.VIBRATE_SETTING_ON;
+            vibeInSilent = false;
+        } else if (value.equals(VALUE_VIBRATE_NEVER)) {
+            callsVibrateSetting = AudioManager.VIBRATE_SETTING_OFF;
+            vibeInSilent = false;
+        } else if (value.equals(VALUE_VIBRATE_ONLY_SILENT)) {
+            callsVibrateSetting = AudioManager.VIBRATE_SETTING_ONLY_SILENT;
+            vibeInSilent = true;
+        } else { //VALUE_VIBRATE_ALWAYS
+            callsVibrateSetting = AudioManager.VIBRATE_SETTING_ON;
+            vibeInSilent = true;
+        }
+
+        Settings.System.putInt(getContentResolver(),
+            Settings.System.VIBRATE_IN_SILENT,
+            vibeInSilent ? 1 : 0);
+
+        // might need to switch the ringer mode from one kind of "silent" to
+        // another
+        if (mSilent.isChecked()) {
+            mAudioManager.setRingerMode(
+                vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
+                             : AudioManager.RINGER_MODE_SILENT);
+        }
+
+        mAudioManager.setVibrateSetting(
+            AudioManager.VIBRATE_TYPE_RINGER,
+            callsVibrateSetting);
+    }
+
     // updateState in fact updates the UI to reflect the system state
     private void updateState(boolean force) {
         final int ringerMode = mAudioManager.getRingerMode();
@@ -183,18 +257,12 @@
             mSilent.setChecked(silentOrVibrateMode);
         }
 
-        mVibrateInSilent.setChecked(Settings.System.getInt(
-            getContentResolver(),
-            Settings.System.VIBRATE_IN_SILENT,
-            1) == 1);
+        String phoneVibrateSetting = getPhoneVibrateSettingValue();
 
-        // Control phone vibe independent of silent mode
-        String phoneVibrateSetting = String.valueOf(
-            mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER));
-
-        if (! phoneVibrateSetting.equals(mPhoneVibrate.getValue()) || force) {
-            mPhoneVibrate.setValue(phoneVibrateSetting);
+        if (! phoneVibrateSetting.equals(mVibrate.getValue()) || force) {
+            mVibrate.setValue(phoneVibrateSetting);
         }
+        mVibrate.setSummary(mVibrate.getEntry());
 
         int silentModeStreams = Settings.System.getInt(getContentResolver(),
                 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
@@ -202,14 +270,16 @@
         mSilent.setSummary(isAlarmInclSilentMode ?
                 R.string.silent_mode_incl_alarm_summary :
                 R.string.silent_mode_summary);
-
     }
 
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
         if (preference == mSilent) {
             if (mSilent.isChecked()) {
-                boolean vibeInSilent = mVibrateInSilent.isChecked();
+                boolean vibeInSilent = (1 == Settings.System.getInt(
+                    getContentResolver(),
+                    Settings.System.VIBRATE_IN_SILENT,
+                    1));
                 mAudioManager.setRingerMode(
                     vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
                                  : AudioManager.RINGER_MODE_SILENT);
@@ -217,17 +287,6 @@
                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
             }
             updateState(false);
-        } else if (preference == mVibrateInSilent) {
-            boolean vibeInSilent = mVibrateInSilent.isChecked();
-            Settings.System.putInt(getContentResolver(),
-                Settings.System.VIBRATE_IN_SILENT,
-                vibeInSilent ? 1 : 0);
-            int ringerMode = mAudioManager.getRingerMode();
-            if (ringerMode != AudioManager.RINGER_MODE_NORMAL) {
-                mAudioManager.setRingerMode(vibeInSilent
-                    ? AudioManager.RINGER_MODE_VIBRATE
-                    : AudioManager.RINGER_MODE_SILENT);
-            }
         } else if (preference == mDtmfTone) {
             Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
                     mDtmfTone.isChecked() ? 1 : 0);
@@ -268,18 +327,9 @@
             } catch (NumberFormatException e) {
                 Log.e(TAG, "could not persist emergency tone setting", e);
             }
-        } else if (preference == mPhoneVibrate) {
-            int vibeSetting = new Integer(objValue.toString()).intValue();
-            switch (vibeSetting) {
-                case AudioManager.VIBRATE_SETTING_ON:
-                case AudioManager.VIBRATE_SETTING_OFF:
-                case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
-                    mAudioManager.setVibrateSetting(
-                            AudioManager.VIBRATE_TYPE_RINGER,
-                            vibeSetting);
-                    updateState(false);
-                    break;
-            }
+        } else if (preference == mVibrate) {
+            setPhoneVibrateSettingValue(objValue.toString());
+            updateState(false);
         }
 
         return true;