Merge "Add correct content descriptions for favorite tab"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 06a461d..075cbea 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1745,6 +1745,7 @@
 
         Note: AccessibilityServices use this attribute to announce what the view represents.
               This is especially valuable for views without textual representation like ImageView.
+              [CHAR LIMIT=NONE]
     -->
     <string name="description_send_text_message">Send text message to <xliff:g id="name">%1$s</xliff:g></string>
 
@@ -1753,9 +1754,32 @@
 
         Note: AccessibilityServices use this attribute to announce what the view represents.
               This is especially valuable for views without textual representation like ImageView.
+              [CHAR LIMIT=NONE]
     -->
     <string name="description_call_log_unheard_voicemail">Unheard voicemail</string>
 
+    <!-- String describing the button to send a text message on quick contact.
+
+        Note: AccessibilityServices use this attribute to announce what the view represents.
+              This is especially valuable for views without textual representation like ImageView.
+              [CHAR LIMIT=NONE]
+    -->
+    <string name="description_send_message">Send message to <xliff:g id="name">%1$s</xliff:g></string>
+
+    <!-- String describing the text for a phone number in quick contact.
+
+        Note: AccessibilityServices use this attribute to announce what the view represents.
+              This is especially valuable for views without textual representation like ImageView.
+    -->
+    <string name="description_dial_phone_number">Dial phone <xliff:g id="name">%1$s</xliff:g></string>
+
+    <!-- String describing the text for photo of a contact in a contacts list.
+
+        Note: AccessibilityServices use this attribute to announce what the view represents.
+              This is especially valuable for views without textual representation like ImageView.
+    -->
+    <string name="description_quick_contact_for">Quick contact for <xliff:g id="name">%1$s</xliff:g></string>
+
     <!-- The string used to represent an unknown location for a phone number in the call log [CHAR LIMIT=3] -->
     <string name="call_log_empty_gecode">-</string>
 
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 25f6fc2..5683e23 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -45,6 +45,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.preference.PreferenceManager;
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Intents.UI;
@@ -94,12 +95,11 @@
 
     private static final int TAB_INDEX_COUNT = 3;
 
-    /** Name of the dialtacts shared preferences */
-    static final String PREFS_DIALTACTS = "dialtacts";
-    static final boolean PREF_FAVORITES_AS_CONTACTS_DEFAULT = false;
+    private SharedPreferences mPrefs;
 
     /** Last manually selected tab index */
-    private static final String PREF_LAST_MANUALLY_SELECTED_TAB = "last_manually_selected_tab";
+    private static final String PREF_LAST_MANUALLY_SELECTED_TAB =
+            "DialtactsActivity_last_manually_selected_tab";
     private static final int PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT = TAB_INDEX_DIALER;
 
     /**
@@ -391,8 +391,8 @@
         getActionBar().setDisplayShowHomeEnabled(false);
 
         // Load the last manually loaded tab
-        final SharedPreferences prefs = getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE);
-        mLastManuallySelectedFragment = prefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB,
+        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+        mLastManuallySelectedFragment = mPrefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB,
                 PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT);
         if (mLastManuallySelectedFragment >= TAB_INDEX_COUNT) {
             // Stored value may have exceeded the number of current tabs. Reset it.
@@ -496,11 +496,8 @@
     protected void onPause() {
         super.onPause();
 
-        final SharedPreferences.Editor editor =
-                getSharedPreferences(PREFS_DIALTACTS, MODE_PRIVATE).edit();
-        editor.putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedFragment);
-
-        editor.apply();
+        mPrefs.edit().putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedFragment)
+                .apply();
     }
 
     private void fixIntent(Intent intent) {
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index a6e241f..f47560b 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -698,6 +698,11 @@
         }
         if (mQuickContact == null) {
             mQuickContact = new QuickContactBadge(mContext, null, QUICK_CONTACT_BADGE_STYLE);
+            if (mNameTextView != null) {
+                mQuickContact.setContentDescription(mContext.getString(
+                        R.string.description_quick_contact_for, mNameTextView.getText()));
+            }
+
             addView(mQuickContact);
             mPhotoViewWidthAndHeightAreReady = false;
         }
@@ -1038,6 +1043,13 @@
 
         mDisplayNameFormatter.setDisplayName(
                 getNameTextView(), displayOrder, highlightingEnabled, mHighlightedPrefix);
+        // Since the quick contact content description is derived from the display name and there is
+        // no guarantee that when the quick contact is initialized the display name is already set,
+        // do it here too.
+        if (mQuickContact != null) {
+            mQuickContact.setContentDescription(mContext.getString(
+                    R.string.description_quick_contact_for, mNameTextView.getText()));
+        }
     }
 
     public void hideDisplayName() {
diff --git a/src/com/android/contacts/quickcontact/QuickContactListFragment.java b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
index 7cbc7c8..cd899fa 100644
--- a/src/com/android/contacts/quickcontact/QuickContactListFragment.java
+++ b/src/com/android/contacts/quickcontact/QuickContactListFragment.java
@@ -20,6 +20,7 @@
 
 import android.app.Fragment;
 import android.os.Bundle;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -115,6 +116,16 @@
                 alternateActionButton.setImageDrawable(action.getAlternateIcon());
                 alternateActionButton.setVisibility(hasAlternateAction ? View.VISIBLE : View.GONE);
 
+                // Special case for phone numbers in accessibility mode
+                if (action.getMimeType().equals(Phone.CONTENT_ITEM_TYPE)) {
+                    text1.setContentDescription(getActivity().getString(
+                            R.string.description_dial_phone_number, action.getBody()));
+                    if (hasAlternateAction) {
+                        alternateActionButton.setContentDescription(getActivity()
+                                .getString(R.string.description_send_message, action.getBody()));
+                    }
+                }
+
                 text1.setText(action.getBody());
                 text2.setText(action.getSubtitle());
 
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetSettings.java b/src/com/android/contacts/socialwidget/SocialWidgetSettings.java
index 18b5041..45a7dfb 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetSettings.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetSettings.java
@@ -20,54 +20,96 @@
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
 import android.net.Uri;
+import android.preference.PreferenceManager;
 import android.util.Log;
 
 public class SocialWidgetSettings {
     private static final String TAG = "SocialWidgetSettings";
 
-    private static final String PREFS_NAME = "WidgetSettings";
+    // To migrate from earlier versions...
+    private static final String LEGACY_PREFS_NAME = "WidgetSettings";
+
+    // Prefix to use for all preferences used by this class.
+    private static final String PREFERENCES_PREFIX = "SocialWidgetSettings_";
+
     private static final String CONTACT_URI_PREFIX = "CONTACT_URI_";
 
+    private static final String KEY_MIGRATED = PREFERENCES_PREFIX + "settings_migrated";
+
     private static final SocialWidgetSettings sInstance = new SocialWidgetSettings();
 
     public static SocialWidgetSettings getInstance() {
         return sInstance;
     }
 
-    private final String getSettingsString(int widgetId) {
-        return CONTACT_URI_PREFIX + Integer.toString(widgetId);
+    private final String getPreferenceKey(int widgetId) {
+        return PREFERENCES_PREFIX + CONTACT_URI_PREFIX + Integer.toString(widgetId);
     }
 
     public void remove(Context context, int[] widgetIds) {
-        final SharedPreferences settings =
-            context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+        final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
         final Editor editor = settings.edit();
         for (int widgetId : widgetIds) {
-            Log.d(TAG, "remove(" + widgetId + ")");
-            editor.remove(getSettingsString(widgetId));
+            if (Log.isLoggable(TAG, Log.DEBUG)) {
+                Log.d(TAG, "remove(" + widgetId + ")");
+            }
+            editor.remove(getPreferenceKey(widgetId));
         }
         editor.apply();
     }
 
     public Uri getContactUri(Context context, int widgetId) {
-        final SharedPreferences settings =
-                context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
-        final String resultString = settings.getString(getSettingsString(widgetId), null);
+        final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
+
+        ensureMigrated(context, settings);
+
+        final String resultString = settings.getString(getPreferenceKey(widgetId), null);
         final Uri result = resultString == null ? null : Uri.parse(resultString);
-        Log.d(TAG, "getContactUri(" + widgetId + ") --> " + result);
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "getContactUri(" + widgetId + ") --> " + result);
+        }
         return result;
     }
 
     public void setContactUri(Context context, int widgetId, Uri contactLookupUri) {
-        Log.d(TAG, "setContactUri(" + widgetId + ", " + contactLookupUri + ")");
-        final SharedPreferences settings =
-                context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, "setContactUri(" + widgetId + ", " + contactLookupUri + ")");
+        }
+        final SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
         final Editor editor = settings.edit();
         if (contactLookupUri == null) {
-            editor.remove(getSettingsString(widgetId));
+            editor.remove(getPreferenceKey(widgetId));
         } else {
-            editor.putString(getSettingsString(widgetId), contactLookupUri.toString());
+            editor.putString(getPreferenceKey(widgetId), contactLookupUri.toString());
         }
         editor.apply();
     }
+
+    private void ensureMigrated(Context context, SharedPreferences settings) {
+        if (settings.getBoolean(KEY_MIGRATED, false)) {
+            return; // Migrated already
+        }
+
+        Log.i(TAG, "Migrating widget settings...");
+
+        // Old preferences only had the "CONTACT_URI_" prefix.
+        // New preferences have the "SocialWidgetSettings_CONTACT_URI_" prefix.
+        // So just copy all the entries with adding "SocialWidgetSettings_" to their key names.
+
+        final SharedPreferences.Editor editor = settings.edit();
+
+        final SharedPreferences legacySettings =
+            context.getSharedPreferences(LEGACY_PREFS_NAME, Context.MODE_PRIVATE);
+        for (String key : legacySettings.getAll().keySet()) {
+            final String value = legacySettings.getString(key, null);
+            if (value == null) continue; // Just in case.
+
+            Log.i(TAG, "Found: " + key + ": " + value);
+
+            editor.putString(PREFERENCES_PREFIX + key, value);
+        }
+
+        editor.apply();
+        settings.edit().putBoolean(KEY_MIGRATED, true).apply();
+    }
 }