From a9bf2b656ad6696339ab771b1bbc9fb366f89c1f Mon Sep 17 00:00:00 2001 From: Erica Chang Date: Thu, 12 May 2016 14:32:47 -0700 Subject: Contacts : handle InCall plugin refresh on configuration change InCallMethod text provided by InCall plugin (nudges, name etc) was not updated on a locale change. This patch addresses the issue by -tracking current locale in SharedPreferences -if the onResume lifecycle comes directly from a configuration change, check if the current locale is different than the saved locale in SharedPreferences. If the locale changed, refreshing all CallMethodInfo (instead of only dynamic items) -Android system global locale update has significant delays, so Application.onConfigurationChanged is not used, instead, the locale check is placed in onResume of affected Activities (PeopleActivity & QuickContactActivity) CD-640 Change-Id: I669a36e6a6739e56215af065c1d1b26909aac450 (cherry picked from commit c68948bc5e1284a32a185c29543473ec3980738b) --- src/com/android/contacts/ContactsApplication.java | 7 +++- .../contacts/activities/PeopleActivity.java | 19 ++++++---- .../android/contacts/incall/InCallPluginUtils.java | 42 ++++++++++++++++++++++ .../list/PluginContactBrowseListFragment.java | 21 +++++------ .../quickcontact/QuickContactActivity.java | 10 ++++-- 5 files changed, 79 insertions(+), 20 deletions(-) diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java index caa3987d6..dcd8047ec 100644 --- a/src/com/android/contacts/ContactsApplication.java +++ b/src/com/android/contacts/ContactsApplication.java @@ -23,10 +23,12 @@ import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Configuration; import android.os.AsyncTask; import android.os.StrictMode; import android.preference.PreferenceManager; import android.provider.ContactsContract.Contacts; +import android.text.TextUtils; import android.util.Log; import com.android.contacts.common.ContactPhotoManager; @@ -35,6 +37,7 @@ import com.android.contacts.common.testing.InjectedServices; import com.android.contacts.common.util.Constants; import com.android.contacts.commonbind.analytics.AnalyticsUtil; import com.android.contacts.incall.InCallMetricsHelper; +import com.android.contacts.incall.InCallPluginUtils; import com.android.phone.common.incall.ContactsDataSubscription; import com.google.common.annotations.VisibleForTesting; @@ -126,6 +129,8 @@ public final class ContactsApplication extends Application { AnalyticsUtil.initialize(this); ContactsDataSubscription.init(this); InCallMetricsHelper.init(this); + // store the current locale to detect future locale configuration changes + InCallPluginUtils.updateSavedLocale(this, ""); } private class DelayedInitializer extends AsyncTask { @@ -147,4 +152,4 @@ public final class ContactsApplication extends Application { (Void[]) null); } } -} +} \ No newline at end of file diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java index 3beabd47d..e405f8064 100644 --- a/src/com/android/contacts/activities/PeopleActivity.java +++ b/src/com/android/contacts/activities/PeopleActivity.java @@ -20,7 +20,6 @@ import android.app.DialogFragment; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; -import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentUris; @@ -143,7 +142,6 @@ public class PeopleActivity extends ContactsActivity implements public static String EDITABLE_KEY = "search_contacts"; private static final String ENABLE_DEBUG_OPTIONS_HIDDEN_CODE = "debug debug!"; - private static final int INCALL_PLUGIN_LOADER_ID = 0; // These values needs to start at 2. See {@link ContactEntryListFragment}. private static final int SUBACTIVITY_ACCOUNT_FILTER = 2; @@ -205,6 +203,8 @@ public class PeopleActivity extends ContactsActivity implements * This is set in {@link #onCreate} for later use in {@link #onStart}. */ private boolean mIsRecreatedInstance; + // flag to track if the onResume cycle is directly from a configuration change + private boolean mConfigurationChanged; /** * If {@link #configureFragments(boolean)} is already called. Used to avoid calling it twice @@ -284,6 +284,7 @@ public class PeopleActivity extends ContactsActivity implements mProviderStatusWatcher.addListener(this); mIsRecreatedInstance = (savedState != null); + mConfigurationChanged = (savedState != null); createViewsAndFragments(savedState); if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { @@ -359,7 +360,6 @@ public class PeopleActivity extends ContactsActivity implements private void createViewsAndFragments(Bundle savedState) { // Disable the ActionBar so that we can use a Toolbar. This needs to be called before // setContentView(). - getWindow().requestFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.people_activity); @@ -382,7 +382,7 @@ public class PeopleActivity extends ContactsActivity implements .favorites_tab_label))); mTabTitles.add(TabState.ALL, new TabEntry(ALL_TAG, getString(R.string .all_contacts_tab_label))); - mTabTitles.add(TabState.GROUPS,new TabEntry(GROUPS_TAG, getString(R.string + mTabTitles.add(TabState.GROUPS, new TabEntry(GROUPS_TAG, getString(R.string .contacts_groups_label))); if (savedState != null) { @@ -410,6 +410,7 @@ public class PeopleActivity extends ContactsActivity implements mPluginTabInfo.clear(); mPluginLength = 0; } + mPageStateCount = TabState.COUNT + mPluginLength; mTabStateGroup = TabState.GROUPS + mPluginLength; @@ -550,18 +551,20 @@ public class PeopleActivity extends ContactsActivity implements super.onPause(); dismissDialog(ImportExportDialogFragment.TAG); dismissDialog(SelectAccountDialogFragment.TAG); + // reset the configuration change flag + mConfigurationChanged = false; } @Override protected void onResume() { super.onResume(); - onResumeInit(); ContactsDataSubscription dataSubscription = ContactsDataSubscription.get(this); if (dataSubscription.subscribe(CALL_METHOD_HELPER_SUBSCRIBER_ID, pluginsUpdatedReceiver)) { if (CallMethodFilters.getAllEnabledCallMethods(dataSubscription).size() > 0) { - dataSubscription.refreshDynamicItems(); + InCallPluginUtils.refreshInCallPlugins(this, mConfigurationChanged, + dataSubscription); } else { // double check if the UI needs to update in case of plugin state changes updatePlugins(null); @@ -1913,6 +1916,10 @@ public class PeopleActivity extends ContactsActivity implements // determine if a UI update is necessary CallMethodInfo newCm = newCmMap.remove(cn); InCallPluginInfo pluginInfo = getPluginInfo(cn); + if (!TextUtils.equals(newCm.mName, pluginInfo.mCallMethodInfo.mName)) { + // plugin name has changed (may be due to locale change), need to update tabs + updateTabs = true; + } pluginInfo.mCallMethodInfo = newCm; pluginInfo.mFragment.updateInCallPluginInfo(pluginInfo); mCallMethodMap.put(cn, newCm); diff --git a/src/com/android/contacts/incall/InCallPluginUtils.java b/src/com/android/contacts/incall/InCallPluginUtils.java index 29e162ddf..cc6504348 100644 --- a/src/com/android/contacts/incall/InCallPluginUtils.java +++ b/src/com/android/contacts/incall/InCallPluginUtils.java @@ -22,10 +22,12 @@ import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.text.TextUtils; import android.util.Log; @@ -55,6 +57,7 @@ import com.google.common.collect.ImmutableMap; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.Locale; public class InCallPluginUtils { private static final String TAG = InCallPluginUtils.class.getSimpleName(); @@ -72,6 +75,9 @@ public class InCallPluginUtils { ".number"; public static final String KEY_NUDGE_KEY = InCallPluginUtils.class.getPackage().getName() + "" + ".nudge_key"; + // SharedPreferences key to keep track of current locale, in case of a locale caused + // configuration change, we need to update plugin provided strings + private static final String PREF_LAST_GLOBAL_LOCALE = "last_global_locale"; public static Drawable getDrawable(Context context, int resourceId, ComponentName componentName) { @@ -260,4 +266,40 @@ public class InCallPluginUtils { } }); } + + // if provided locale is null or empty, look up the current locale + public static void updateSavedLocale(Context context, String locale) { + if (TextUtils.isEmpty(locale)) { + locale = getCurrentLocale(context); + } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + prefs.edit().putString(InCallPluginUtils.PREF_LAST_GLOBAL_LOCALE, locale).apply(); + if (DEBUG) { + Log.d(TAG, "current locale:" + context.getResources().getConfiguration().locale + .toString()); + } + } + + private static String getSavedLocale(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context).getString + (PREF_LAST_GLOBAL_LOCALE, ""); + } + + public static String getCurrentLocale(Context context) { + Locale current = context.getResources().getConfiguration().locale; + return current == null ? "" : current.toString(); + } + + public static void refreshInCallPlugins(Context context, boolean configChanged, + ContactsDataSubscription subscription) { + String currentLocale = getCurrentLocale(context); + if (configChanged && !TextUtils.equals(currentLocale, getSavedLocale(context))) { + // locale has changed, refresh all plugin info and update saved locale + subscription.refresh(); + updateSavedLocale(context, currentLocale); + } else { + // only refresh dynamic plugin info + subscription.refreshDynamicItems(); + } + } } diff --git a/src/com/android/contacts/list/PluginContactBrowseListFragment.java b/src/com/android/contacts/list/PluginContactBrowseListFragment.java index 442d4e8c8..cbb37deff 100644 --- a/src/com/android/contacts/list/PluginContactBrowseListFragment.java +++ b/src/com/android/contacts/list/PluginContactBrowseListFragment.java @@ -722,16 +722,17 @@ public class PluginContactBrowseListFragment extends ContactEntryListFragment mRecentDataTask; private AtomicBoolean mIsUpdating; private static final String CALL_METHOD_SUBSCRIBER_ID = TAG; + // flag to track if the onResume cycle is directly from a configuration change + private boolean mConfigurationChanged; /** * The last copy of Cp2DataCardModel that was passed to {@link #populateContactAndAboutCard}. */ @@ -966,6 +968,7 @@ public class QuickContactActivity extends ContactsActivity implements mBlockContactHelper.setContactInfo(mContactData); mBlockContactHelper.gatherDataInBackground(); } + mConfigurationChanged = (savedInstanceState != null); Trace.endSection(); } @@ -1303,9 +1306,10 @@ public class QuickContactActivity extends ContactsActivity implements ContactsDataSubscription dataSubscription = ContactsDataSubscription.get(this); if (dataSubscription.subscribe(CALL_METHOD_SUBSCRIBER_ID, pluginsUpdatedReceiver)) { if (DEBUG) Log.d(TAG, "ContactsDataSubscription infoReady"); - if (CallMethodFilters.getAllEnabledCallMethods(dataSubscription).size() > 0) { + if (CallMethodFilters.getAllEnabledAndHiddenCallMethods(dataSubscription).size() > 0) { // only refresh if there are ENABLED plugins - dataSubscription.refreshDynamicItems(); + InCallPluginUtils.refreshInCallPlugins(this, mConfigurationChanged, + dataSubscription); } else { // double check if UI needs update in case plugin status changes between // ENABLED and DISABLED or ENABLED and HIDDEN or DISABLED and HIDDEN @@ -1333,7 +1337,7 @@ public class QuickContactActivity extends ContactsActivity implements @Override protected void onPause() { super.onPause(); - + mConfigurationChanged = false; ContactsDataSubscription.get(this).unsubscribe(CALL_METHOD_SUBSCRIBER_ID); } -- cgit v1.2.3