Merge change 1110 into donut
* changes:
Track install/removal/update of packages that provide backup services
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index cd44277..8fc2447 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -601,11 +601,11 @@
CharSequence text = null;
// optionally show one or the other.
- if (mSearchable.mBadgeIcon) {
+ if (mSearchable.useBadgeIcon()) {
icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
visibility = View.VISIBLE;
if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
- } else if (mSearchable.mBadgeLabel) {
+ } else if (mSearchable.useBadgeLabel()) {
text = mActivityContext.getResources().getText(mSearchable.getLabelId()).toString();
visibility = View.VISIBLE;
if (DBG) Log.d(LOG_TAG, "Using badge label: " + mSearchable.getLabelId());
@@ -714,8 +714,8 @@
// if it's an action specified by the searchable activity, launch the
// entered query with the action key
SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
- if ((actionKey != null) && (actionKey.mQueryActionMsg != null)) {
- launchQuerySearch(keyCode, actionKey.mQueryActionMsg);
+ if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) {
+ launchQuerySearch(keyCode, actionKey.getQueryActionMsg());
return true;
}
@@ -830,7 +830,7 @@
// in the voice search system. We have to keep the bundle separate,
// because it becomes immutable once it enters the PendingIntent
Intent queryIntent = new Intent(Intent.ACTION_SEARCH);
- queryIntent.setComponent(mSearchable.mSearchActivity);
+ queryIntent.setComponent(mSearchable.getSearchActivity());
PendingIntent pending = PendingIntent.getActivity(
getContext(), 0, queryIntent, PendingIntent.FLAG_ONE_SHOT);
@@ -913,8 +913,8 @@
}
if (event.getAction() == KeyEvent.ACTION_DOWN) {
SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
- if ((actionKey != null) && (actionKey.mQueryActionMsg != null)) {
- launchQuerySearch(keyCode, actionKey.mQueryActionMsg);
+ if ((actionKey != null) && (actionKey.getQueryActionMsg() != null)) {
+ launchQuerySearch(keyCode, actionKey.getQueryActionMsg());
return true;
}
}
@@ -1010,8 +1010,8 @@
// Next, check for an "action key"
SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
if ((actionKey != null) &&
- ((actionKey.mSuggestActionMsg != null) ||
- (actionKey.mSuggestActionMsgColumn != null))) {
+ ((actionKey.getSuggestActionMsg() != null) ||
+ (actionKey.getSuggestActionMsgColumn() != null))) {
// launch suggestion using action key column
int position = mSearchAutoComplete.getListSelection();
if (position != ListView.INVALID_POSITION) {
@@ -1292,7 +1292,7 @@
intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
}
// attempt to enforce security requirement (no 3rd-party intents)
- intent.setComponent(mSearchable.mSearchActivity);
+ intent.setComponent(mSearchable.getSearchActivity());
return intent;
}
@@ -1308,14 +1308,14 @@
private static String getActionKeyMessage(Cursor c, SearchableInfo.ActionKeyInfo actionKey) {
String result = null;
// check first in the cursor data, for a suggestion-specific message
- final String column = actionKey.mSuggestActionMsgColumn;
+ final String column = actionKey.getSuggestActionMsgColumn();
if (column != null) {
result = SuggestionsAdapter.getColumnString(c, column);
}
// If the cursor didn't give us a message, see if there's a single message defined
// for the actionkey (for all suggestions)
if (result == null) {
- result = actionKey.mSuggestActionMsg;
+ result = actionKey.getSuggestActionMsg();
}
return result;
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 39f3bcd1..2d2f98a 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1602,7 +1602,7 @@
public static boolean isDefaultSearchable(SearchableInfo searchable) {
SearchableInfo defaultSearchable = SearchManager.getSearchableInfo(null, true);
return defaultSearchable != null
- && defaultSearchable.mSearchActivity.equals(searchable.mSearchActivity);
+ && defaultSearchable.getSearchActivity().equals(searchable.getSearchActivity());
}
/**
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index af2a321..6a02fc9 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -231,14 +231,14 @@
return query;
}
- if (mSearchable.mQueryRewriteFromData) {
+ if (mSearchable.shouldRewriteQueryFromData()) {
String data = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_INTENT_DATA);
if (data != null) {
return data;
}
}
- if (mSearchable.mQueryRewriteFromText) {
+ if (mSearchable.shouldRewriteQueryFromText()) {
String text1 = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_TEXT_1);
if (text1 != null) {
return text1;
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index aad7ae2..842fc75 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -35,14 +35,13 @@
import android.view.inputmethod.EditorInfo;
import java.io.IOException;
+import java.util.HashMap;
public final class SearchableInfo implements Parcelable {
// general debugging support
- final static String LOG_TAG = "SearchableInfo";
-
- // set this flag to 1 to prevent any apps from providing suggestions
- final static int DBG_INHIBIT_SUGGESTIONS = 0;
+ private static final boolean DBG = true;
+ private static final String LOG_TAG = "SearchableInfo";
// static strings used for XML lookups.
// TODO how should these be documented for the developer, in a more structured way than
@@ -51,40 +50,44 @@
private static final String MD_XML_ELEMENT_SEARCHABLE = "searchable";
private static final String MD_XML_ELEMENT_SEARCHABLE_ACTION_KEY = "actionkey";
+ // flags in the searchMode attribute
+ private static final int SEARCH_MODE_BADGE_LABEL = 0x04;
+ private static final int SEARCH_MODE_BADGE_ICON = 0x08;
+ private static final int SEARCH_MODE_QUERY_REWRITE_FROM_DATA = 0x10;
+ private static final int SEARCH_MODE_QUERY_REWRITE_FROM_TEXT = 0x20;
+
// true member variables - what we know about the searchability
- // TO-DO replace public with getters
- public boolean mSearchable = false;
- private int mLabelId = 0;
- public ComponentName mSearchActivity = null;
- private int mHintId = 0;
- private int mSearchMode = 0;
- public boolean mBadgeLabel = false;
- public boolean mBadgeIcon = false;
- public boolean mQueryRewriteFromData = false;
- public boolean mQueryRewriteFromText = false;
- private int mIconId = 0;
- private int mSearchButtonText = 0;
- private int mSearchInputType = 0;
- private int mSearchImeOptions = 0;
- private boolean mIncludeInGlobalSearch = false;
- private String mSuggestAuthority = null;
- private String mSuggestPath = null;
- private String mSuggestSelection = null;
- private String mSuggestIntentAction = null;
- private String mSuggestIntentData = null;
- private int mSuggestThreshold = 0;
- private ActionKeyInfo mActionKeyList = null;
- private String mSuggestProviderPackage = null;
+ private final int mLabelId;
+ private final ComponentName mSearchActivity;
+ private final int mHintId;
+ private final int mSearchMode;
+ private final int mIconId;
+ private final int mSearchButtonText;
+ private final int mSearchInputType;
+ private final int mSearchImeOptions;
+ private final boolean mIncludeInGlobalSearch;
+ private final String mSuggestAuthority;
+ private final String mSuggestPath;
+ private final String mSuggestSelection;
+ private final String mSuggestIntentAction;
+ private final String mSuggestIntentData;
+ private final int mSuggestThreshold;
+ // Maps key codes to action key information. auto-boxing is not so bad here,
+ // since keycodes for the hard keys are < 127. For such values, Integer.valueOf()
+ // uses shared Integer objects.
+ // This is not final, to allow lazy initialization.
+ private HashMap<Integer,ActionKeyInfo> mActionKeys = null;
+ private final String mSuggestProviderPackage;
// Flag values for Searchable_voiceSearchMode
private static int VOICE_SEARCH_SHOW_BUTTON = 1;
private static int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
private static int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
- private int mVoiceSearchMode = 0;
- private int mVoiceLanguageModeId; // voiceLanguageModel
- private int mVoicePromptTextId; // voicePromptText
- private int mVoiceLanguageId; // voiceLanguage
- private int mVoiceMaxResults; // voiceMaxResults
+ private final int mVoiceSearchMode;
+ private final int mVoiceLanguageModeId; // voiceLanguageModel
+ private final int mVoicePromptTextId; // voicePromptText
+ private final int mVoiceLanguageId; // voiceLanguage
+ private final int mVoiceMaxResults; // voiceMaxResults
/**
@@ -95,7 +98,42 @@
public String getSuggestAuthority() {
return mSuggestAuthority;
}
-
+
+ /**
+ * Gets the component name of the searchable activity.
+ */
+ public ComponentName getSearchActivity() {
+ return mSearchActivity;
+ }
+
+ /**
+ * Checks whether the badge should be a text label.
+ */
+ public boolean useBadgeLabel() {
+ return 0 != (mSearchMode & SEARCH_MODE_BADGE_LABEL);
+ }
+
+ /**
+ * Checks whether the badge should be an icon.
+ */
+ public boolean useBadgeIcon() {
+ return (0 != (mSearchMode & SEARCH_MODE_BADGE_ICON)) && (mIconId != 0);
+ }
+
+ /**
+ * Checks whether the text in the query field should come from the suggestion intent data.
+ */
+ public boolean shouldRewriteQueryFromData() {
+ return 0 != (mSearchMode & SEARCH_MODE_QUERY_REWRITE_FROM_DATA);
+ }
+
+ /**
+ * Checks whether the text in the query field should come from the suggestion title.
+ */
+ public boolean shouldRewriteQueryFromText() {
+ return 0 != (mSearchMode & SEARCH_MODE_QUERY_REWRITE_FROM_TEXT);
+ }
+
/**
* Retrieve the path for obtaining search suggestions.
*
@@ -218,10 +256,9 @@
* @param attr The attribute set we found in the XML file, contains the values that are used to
* construct the object.
* @param cName The component name of the searchable activity
+ * @throws IllegalArgumentException if the searchability info is invalid or insufficient
*/
private SearchableInfo(Context activityContext, AttributeSet attr, final ComponentName cName) {
- // initialize as an "unsearchable" object
- mSearchable = false;
mSearchActivity = cName;
TypedArray a = activityContext.obtainStyledAttributes(attr,
@@ -240,21 +277,19 @@
mIncludeInGlobalSearch = a.getBoolean(
com.android.internal.R.styleable.Searchable_includeInGlobalSearch, false);
- setSearchModeFlags();
- if (DBG_INHIBIT_SUGGESTIONS == 0) {
- mSuggestAuthority = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestAuthority);
- mSuggestPath = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestPath);
- mSuggestSelection = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestSelection);
- mSuggestIntentAction = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestIntentAction);
- mSuggestIntentData = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestIntentData);
- mSuggestThreshold = a.getInt(
- com.android.internal.R.styleable.Searchable_searchSuggestThreshold, 0);
- }
+ mSuggestAuthority = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestAuthority);
+ mSuggestPath = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestPath);
+ mSuggestSelection = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestSelection);
+ mSuggestIntentAction = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestIntentAction);
+ mSuggestIntentData = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestIntentData);
+ mSuggestThreshold = a.getInt(
+ com.android.internal.R.styleable.Searchable_searchSuggestThreshold, 0);
+
mVoiceSearchMode =
a.getInt(com.android.internal.R.styleable.Searchable_voiceSearchMode, 0);
// TODO this didn't work - came back zero from YouTube
@@ -270,44 +305,31 @@
a.recycle();
// get package info for suggestions provider (if any)
+ String suggestProviderPackage = null;
if (mSuggestAuthority != null) {
PackageManager pm = activityContext.getPackageManager();
ProviderInfo pi = pm.resolveContentProvider(mSuggestAuthority, 0);
if (pi != null) {
- mSuggestProviderPackage = pi.packageName;
+ suggestProviderPackage = pi.packageName;
}
}
+ mSuggestProviderPackage = suggestProviderPackage;
// for now, implement some form of rules - minimal data
- if (mLabelId != 0) {
- mSearchable = true;
- } else {
- // Provide some help for developers instead of just silently discarding
- Log.w(LOG_TAG, "Insufficient metadata to configure searchability for " +
- cName.flattenToShortString());
+ if (mLabelId == 0) {
+ throw new IllegalArgumentException("No label.");
}
}
-
- /**
- * Convert searchmode to flags.
- */
- private void setSearchModeFlags() {
- mBadgeLabel = (0 != (mSearchMode & 4));
- mBadgeIcon = (0 != (mSearchMode & 8)) && (mIconId != 0);
- mQueryRewriteFromData = (0 != (mSearchMode & 0x10));
- mQueryRewriteFromText = (0 != (mSearchMode & 0x20));
- }
/**
* Private class used to hold the "action key" configuration
*/
public static class ActionKeyInfo implements Parcelable {
- public int mKeyCode = 0;
- public String mQueryActionMsg;
- public String mSuggestActionMsg;
- public String mSuggestActionMsgColumn;
- private ActionKeyInfo mNext;
+ private final int mKeyCode;
+ private final String mQueryActionMsg;
+ private final String mSuggestActionMsg;
+ private final String mSuggestActionMsgColumn;
/**
* Create one object using attributeset as input data.
@@ -315,10 +337,9 @@
* is about.
* @param attr The attribute set we found in the XML file, contains the values that are used to
* construct the object.
- * @param next We'll build these up using a simple linked list (since there are usually
- * just zero or one).
+ * @throws IllegalArgumentException if the action key configuration is invalid
*/
- public ActionKeyInfo(Context activityContext, AttributeSet attr, ActionKeyInfo next) {
+ public ActionKeyInfo(Context activityContext, AttributeSet attr) {
TypedArray a = activityContext.obtainStyledAttributes(attr,
com.android.internal.R.styleable.SearchableActionKey);
@@ -326,23 +347,20 @@
com.android.internal.R.styleable.SearchableActionKey_keycode, 0);
mQueryActionMsg = a.getString(
com.android.internal.R.styleable.SearchableActionKey_queryActionMsg);
- if (DBG_INHIBIT_SUGGESTIONS == 0) {
- mSuggestActionMsg = a.getString(
- com.android.internal.R.styleable.SearchableActionKey_suggestActionMsg);
- mSuggestActionMsgColumn = a.getString(
- com.android.internal.R.styleable.SearchableActionKey_suggestActionMsgColumn);
- }
+ mSuggestActionMsg = a.getString(
+ com.android.internal.R.styleable.SearchableActionKey_suggestActionMsg);
+ mSuggestActionMsgColumn = a.getString(
+ com.android.internal.R.styleable.SearchableActionKey_suggestActionMsgColumn);
a.recycle();
- // initialize any other fields
- mNext = next;
-
- // sanity check. must have at least one action message, or invalidate the object.
- if ((mQueryActionMsg == null) &&
+ // sanity check.
+ if (mKeyCode == 0) {
+ throw new IllegalArgumentException("No keycode.");
+ } else if ((mQueryActionMsg == null) &&
(mSuggestActionMsg == null) &&
(mSuggestActionMsgColumn == null)) {
- mKeyCode = 0;
- }
+ throw new IllegalArgumentException("No message information.");
+ }
}
/**
@@ -351,14 +369,28 @@
*
* @param in The Parcel containing the previously written ActionKeyInfo,
* positioned at the location in the buffer where it was written.
- * @param next The value to place in mNext, creating a linked list
*/
- public ActionKeyInfo(Parcel in, ActionKeyInfo next) {
+ public ActionKeyInfo(Parcel in) {
mKeyCode = in.readInt();
mQueryActionMsg = in.readString();
mSuggestActionMsg = in.readString();
mSuggestActionMsgColumn = in.readString();
- mNext = next;
+ }
+
+ public int getKeyCode() {
+ return mKeyCode;
+ }
+
+ public String getQueryActionMsg() {
+ return mQueryActionMsg;
+ }
+
+ public String getSuggestActionMsg() {
+ return mSuggestActionMsg;
+ }
+
+ public String getSuggestActionMsgColumn() {
+ return mSuggestActionMsgColumn;
}
public int describeContents() {
@@ -380,16 +412,19 @@
* @return Returns the ActionKeyInfo record, or null if none defined
*/
public ActionKeyInfo findActionKey(int keyCode) {
- ActionKeyInfo info = mActionKeyList;
- while (info != null) {
- if (info.mKeyCode == keyCode) {
- return info;
- }
- info = info.mNext;
+ if (mActionKeys == null) {
+ return null;
}
- return null;
+ return mActionKeys.get(keyCode);
}
-
+
+ private void addActionKey(ActionKeyInfo keyInfo) {
+ if (mActionKeys == null) {
+ mActionKeys = new HashMap<Integer,ActionKeyInfo>();
+ }
+ mActionKeys.put(keyInfo.getKeyCode(), keyInfo);
+ }
+
public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
// for each component, try to find metadata
XmlResourceParser xml =
@@ -401,14 +436,22 @@
SearchableInfo searchable = getActivityMetaData(context, xml, cName);
xml.close();
+
+ if (DBG) {
+ Log.d(LOG_TAG, "Checked " + activityInfo.name
+ + ",label=" + searchable.getLabelId()
+ + ",icon=" + searchable.getIconId()
+ + ",suggestAuthority=" + searchable.getSuggestAuthority()
+ + ",target=" + searchable.getSearchActivity().getClassName()
+ + ",global=" + searchable.shouldIncludeInGlobalSearch()
+ + ",threshold=" + searchable.getSuggestThreshold());
+ }
return searchable;
}
/**
* Get the metadata for a given activity
*
- * TODO: clean up where we return null vs. where we throw exceptions.
- *
* @param context runtime context
* @param xml XML parser for reading attributes
* @param cName The component name of the searchable activity
@@ -429,9 +472,11 @@
if (xml.getName().equals(MD_XML_ELEMENT_SEARCHABLE)) {
AttributeSet attr = Xml.asAttributeSet(xml);
if (attr != null) {
- result = new SearchableInfo(activityContext, attr, cName);
- // if the constructor returned a bad object, exit now.
- if (! result.mSearchable) {
+ try {
+ result = new SearchableInfo(activityContext, attr, cName);
+ } catch (IllegalArgumentException ex) {
+ Log.w(LOG_TAG, "Invalid searchable metadata for " +
+ cName.flattenToShortString() + ": " + ex.getMessage());
return null;
}
}
@@ -442,11 +487,12 @@
}
AttributeSet attr = Xml.asAttributeSet(xml);
if (attr != null) {
- ActionKeyInfo keyInfo = new ActionKeyInfo(activityContext, attr,
- result.mActionKeyList);
- // only add to list if it is was useable
- if (keyInfo.mKeyCode != 0) {
- result.mActionKeyList = keyInfo;
+ try {
+ result.addActionKey(new ActionKeyInfo(activityContext, attr));
+ } catch (IllegalArgumentException ex) {
+ Log.w(LOG_TAG, "Invalid action key for " +
+ cName.flattenToShortString() + ": " + ex.getMessage());
+ return null;
}
}
}
@@ -454,14 +500,16 @@
tagType = xml.next();
}
} catch (XmlPullParserException e) {
- throw new RuntimeException(e);
+ Log.w(LOG_TAG, "Reading searchable metadata for " + cName.flattenToShortString(), e);
+ return null;
} catch (IOException e) {
- throw new RuntimeException(e);
+ Log.w(LOG_TAG, "Reading searchable metadata for " + cName.flattenToShortString(), e);
+ return null;
}
return result;
}
-
+
/**
* Return the "label" (user-visible name) of this searchable context. This must be
* accessed using the target (searchable) Activity's resources, not simply the context of the
@@ -610,7 +658,6 @@
* positioned at the location in the buffer where it was written.
*/
public SearchableInfo(Parcel in) {
- mSearchable = in.readInt() != 0;
mLabelId = in.readInt();
mSearchActivity = ComponentName.readFromParcel(in);
mHintId = in.readInt();
@@ -620,7 +667,6 @@
mSearchInputType = in.readInt();
mSearchImeOptions = in.readInt();
mIncludeInGlobalSearch = in.readInt() != 0;
- setSearchModeFlags();
mSuggestAuthority = in.readString();
mSuggestPath = in.readString();
@@ -629,12 +675,10 @@
mSuggestIntentData = in.readString();
mSuggestThreshold = in.readInt();
- mActionKeyList = null;
- int count = in.readInt();
- while (count-- > 0) {
- mActionKeyList = new ActionKeyInfo(in, mActionKeyList);
+ for (int count = in.readInt(); count > 0; count--) {
+ addActionKey(new ActionKeyInfo(in));
}
-
+
mSuggestProviderPackage = in.readString();
mVoiceSearchMode = in.readInt();
@@ -649,7 +693,6 @@
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mSearchable ? 1 : 0);
dest.writeInt(mLabelId);
mSearchActivity.writeToParcel(dest, flags);
dest.writeInt(mHintId);
@@ -667,20 +710,15 @@
dest.writeString(mSuggestIntentData);
dest.writeInt(mSuggestThreshold);
- // This is usually a very short linked list so we'll just pre-count it
- ActionKeyInfo nextKeyInfo = mActionKeyList;
- int count = 0;
- while (nextKeyInfo != null) {
- ++count;
- nextKeyInfo = nextKeyInfo.mNext;
+ if (mActionKeys == null) {
+ dest.writeInt(0);
+ } else {
+ dest.writeInt(mActionKeys.size());
+ for (ActionKeyInfo actionKey : mActionKeys.values()) {
+ actionKey.writeToParcel(dest, flags);
+ }
}
- dest.writeInt(count);
- // Now write count of 'em
- nextKeyInfo = mActionKeyList;
- while (count-- > 0) {
- nextKeyInfo.writeToParcel(dest, flags);
- }
-
+
dest.writeString(mSuggestProviderPackage);
dest.writeInt(mVoiceSearchMode);
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index 40d7449..9586d56 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -210,7 +210,7 @@
SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
if (searchable != null) {
newSearchablesList.add(searchable);
- newSearchablesMap.put(searchable.mSearchActivity, searchable);
+ newSearchablesMap.put(searchable.getSearchActivity(), searchable);
if (searchable.shouldIncludeInGlobalSearch()) {
newSearchablesInGlobalSearchList.add(searchable);
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 20c54fb..1ff0f7e 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -490,7 +490,7 @@
if (null == language) {
return; // no match possible
}
- language.toLowerCase();
+ language = language.toLowerCase();
if (null == country) {
country = "";
}
@@ -503,13 +503,12 @@
final int N = locales.length;
String bestMatch = null;
for(int i = 0; i < N; i++) {
- if (locales[i]!=null && locales[i].length() >= 2 &&
+ // only match full (lang + country) locales
+ if (locales[i]!=null && locales[i].length() >= 5 &&
locales[i].substring(0,2).equals(language)) {
- if (locales[i].length() >= 5) {
- if (locales[i].substring(3,5).equals(country)) {
- bestMatch = locales[i];
- break;
- }
+ if (locales[i].substring(3,5).equals(country)) {
+ bestMatch = locales[i];
+ break;
} else if (null == bestMatch) {
bestMatch = locales[i];
}
@@ -518,12 +517,8 @@
if (null != bestMatch) {
IActivityManager am = ActivityManagerNative.getDefault();
Configuration config = am.getConfiguration();
- if (bestMatch.length() >= 5) {
- config.locale = new Locale(bestMatch.substring(0,2),
- bestMatch.substring(3,5));
- } else {
- config.locale = new Locale(bestMatch.substring(0,2));
- }
+ config.locale = new Locale(bestMatch.substring(0,2),
+ bestMatch.substring(3,5));
config.userSetLocale = true;
am.updateConfiguration(config);
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
index 743c979..bdf67ba 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
@@ -87,8 +87,7 @@
SearchableInfo si = searchables.getSearchableInfo(thisActivity);
assertNotNull(si);
- assertTrue(si.mSearchable);
- assertEquals(thisActivity, si.mSearchActivity);
+ assertEquals(thisActivity, si.getSearchActivity());
Context appContext = si.getActivityContext(mContext);
assertNotNull(appContext);
@@ -194,10 +193,9 @@
private void checkSearchable(SearchableInfo si) {
assertNotNull(si);
- assertTrue(si.mSearchable);
assertTrue(si.getLabelId() != 0); // This must be a useable string
- assertNotEmpty(si.mSearchActivity.getClassName());
- assertNotEmpty(si.mSearchActivity.getPackageName());
+ assertNotEmpty(si.getSearchActivity().getClassName());
+ assertNotEmpty(si.getSearchActivity().getPackageName());
if (si.getSuggestAuthority() != null) {
// The suggestion fields are largely optional, so we'll just confirm basic health
assertNotEmpty(si.getSuggestAuthority());
@@ -210,12 +208,12 @@
/* For now, test the most common action key (CALL) */
ActionKeyInfo ai = si.findActionKey(KeyEvent.KEYCODE_CALL);
if (ai != null) {
- assertEquals(ai.mKeyCode, KeyEvent.KEYCODE_CALL);
+ assertEquals(ai.getKeyCode(), KeyEvent.KEYCODE_CALL);
// one of these three fields must be non-null & non-empty
- boolean m1 = (ai.mQueryActionMsg != null) && (ai.mQueryActionMsg.length() > 0);
- boolean m2 = (ai.mSuggestActionMsg != null) && (ai.mSuggestActionMsg.length() > 0);
- boolean m3 = (ai.mSuggestActionMsgColumn != null) &&
- (ai.mSuggestActionMsgColumn.length() > 0);
+ boolean m1 = (ai.getQueryActionMsg() != null) && (ai.getQueryActionMsg().length() > 0);
+ boolean m2 = (ai.getSuggestActionMsg() != null) && (ai.getSuggestActionMsg().length() > 0);
+ boolean m3 = (ai.getSuggestActionMsgColumn() != null) &&
+ (ai.getSuggestActionMsgColumn().length() > 0);
assertTrue(m1 || m2 || m3);
}