summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/SearchDialog.java26
-rw-r--r--core/java/android/app/Service.java6
-rw-r--r--core/java/android/content/SearchRecentSuggestionsProvider.java6
-rw-r--r--core/java/android/database/MatrixCursor.java6
-rw-r--r--core/java/android/hardware/Camera.java18
-rw-r--r--core/java/android/os/RecoverySystem.java15
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java36
-rw-r--r--core/java/android/util/Patterns.java12
-rw-r--r--core/java/android/view/ActionMode.java30
-rw-r--r--core/java/android/view/View.java16
-rw-r--r--core/java/android/view/ViewGroup.java53
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java11
-rw-r--r--core/java/android/webkit/WebViewCore.java4
-rw-r--r--core/java/android/widget/Gallery.java183
-rw-r--r--core/java/android/widget/GridLayout.java57
-rw-r--r--core/java/android/widget/SearchView.java117
-rw-r--r--core/java/android/widget/SuggestionsAdapter.java37
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl2
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp43
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h6
-rw-r--r--core/res/res/layout/search_bar.xml1
-rw-r--r--core/res/res/layout/search_dropdown_item_icons_2line.xml8
-rw-r--r--core/res/res/layout/search_view.xml33
-rw-r--r--core/res/res/values/dimens.xml9
-rw-r--r--core/res/res/values/styles.xml4
-rw-r--r--core/tests/coretests/src/android/database/MatrixCursorTest.java24
-rw-r--r--core/tests/coretests/src/android/util/JsonReaderTest.java2
-rw-r--r--core/tests/coretests/src/android/util/PatternsTest.java7
28 files changed, 490 insertions, 282 deletions
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 42eda02..8e2d360 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -168,6 +168,7 @@ public class SearchDialog extends Dialog {
SearchBar searchBar = (SearchBar) findViewById(com.android.internal.R.id.search_bar);
searchBar.setSearchDialog(this);
mSearchView = (SearchView) findViewById(com.android.internal.R.id.search_view);
+ mSearchView.setIconified(false);
mSearchView.setOnCloseListener(mOnCloseListener);
mSearchView.setOnQueryTextListener(mOnQueryChangeListener);
mSearchView.setOnSuggestionListener(mOnSuggestionSelectionListener);
@@ -633,31 +634,6 @@ public class SearchDialog extends Dialog {
}
/**
- * Overrides the handling of the back key to move back to the previous
- * sources or dismiss the search dialog, instead of dismissing the input
- * method.
- */
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent event) {
- if (DBG)
- Log.d(LOG_TAG, "onKeyPreIme(" + event + ")");
- if (mSearchDialog != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- KeyEvent.DispatcherState state = getKeyDispatcherState();
- if (state != null) {
- if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
- state.startTracking(event, this);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()
- && state.isTracking(event)) {
- mSearchDialog.onBackPressed();
- return true;
- }
- }
- }
- return super.dispatchKeyEventPreIme(event);
- }
-
- /**
* Don't allow action modes in a SearchBar, it looks silly.
*/
@Override
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index c179b35..4c21d04 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -662,12 +662,6 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
writer.println("nothing to dump");
}
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- //Log.i("Service", "Finalizing Service: " + this);
- }
// ------------------ Internal API ------------------
diff --git a/core/java/android/content/SearchRecentSuggestionsProvider.java b/core/java/android/content/SearchRecentSuggestionsProvider.java
index 3d89e92..e1a8d21 100644
--- a/core/java/android/content/SearchRecentSuggestionsProvider.java
+++ b/core/java/android/content/SearchRecentSuggestionsProvider.java
@@ -186,6 +186,9 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
mSuggestionProjection = new String [] {
"0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
+ "'android.resource://system/"
+ + com.android.internal.R.drawable.ic_menu_recent_history + "' AS "
+ + SearchManager.SUGGEST_COLUMN_ICON_1,
"display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
"display2 AS " + SearchManager.SUGGEST_COLUMN_TEXT_2,
"query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
@@ -196,6 +199,9 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
mSuggestionProjection = new String [] {
"0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
+ "'android.resource://system/"
+ + com.android.internal.R.drawable.ic_menu_recent_history + "' AS "
+ + SearchManager.SUGGEST_COLUMN_ICON_1,
"display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
"query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
"_id"
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
index 5c1b968..6e68b6b 100644
--- a/core/java/android/database/MatrixCursor.java
+++ b/core/java/android/database/MatrixCursor.java
@@ -272,6 +272,12 @@ public class MatrixCursor extends AbstractCursor {
}
@Override
+ public byte[] getBlob(int column) {
+ Object value = get(column);
+ return (byte[]) value;
+ }
+
+ @Override
public int getType(int column) {
return DatabaseUtils.getTypeOfObject(get(column));
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 7d67e11..a168260 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -16,6 +16,8 @@
package android.hardware;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
@@ -142,6 +144,22 @@ public class Camera {
private boolean mWithBuffer;
/**
+ * Broadcast Action: A new picture is taken by the camera, and the entry of
+ * the picture has been added to the media store.
+ * {@link android.content.Intent#getData} is URI of the picture.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_NEW_PICTURE = "android.hardware.action.NEW_PICTURE";
+
+ /**
+ * Broadcast Action: A new video is recorded by the camera, and the entry
+ * of the video has been added to the media store.
+ * {@link android.content.Intent#getData} is URI of the video.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_NEW_VIDEO = "android.hardware.action.NEW_VIDEO";
+
+ /**
* Returns the number of physical cameras available on this device.
*/
public native static int getNumberOfCameras();
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index ae605fb..73e8d98 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -357,20 +357,11 @@ public class RecoverySystem {
}
/**
- * Reboot into the recovery system to wipe the /data partition and toggle
- * Encrypted File Systems on/off.
- * @param extras to add to the RECOVERY_COMPLETED intent after rebooting.
+ * Reboot into the recovery system to wipe the /cache partition.
* @throws IOException if something goes wrong.
- *
- * @hide
*/
- public static void rebootToggleEFS(Context context, boolean efsEnabled)
- throws IOException {
- if (efsEnabled) {
- bootCommand(context, "--set_encrypted_filesystem=on");
- } else {
- bootCommand(context, "--set_encrypted_filesystem=off");
- }
+ public static void rebootWipeCache(Context context) throws IOException {
+ bootCommand(context, "--wipe_cache");
}
/**
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 96864c4..255b333 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -418,22 +418,30 @@ class AudioPlaybackHandler {
if (DBG) Log.d(TAG, "handleSynthesisDone()");
final AudioTrack audioTrack = params.getAudioTrack();
- try {
- if (audioTrack != null) {
- if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
- audioTrack.hashCode());
- blockUntilDone(params);
- if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
- // The last call to AudioTrack.write( ) will return only after
- // all data from the audioTrack has been sent to the mixer, so
- // it's safe to release at this point.
- audioTrack.release();
- }
- } finally {
+ if (audioTrack == null) {
+ return;
+ }
+
+ if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
+ audioTrack.hashCode());
+ blockUntilDone(params);
+ if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
+
+ // The last call to AudioTrack.write( ) will return only after
+ // all data from the audioTrack has been sent to the mixer, so
+ // it's safe to release at this point. Make sure release() and the call
+ // that set the audio track to null are performed atomically.
+ synchronized (this) {
+ // Never allow the audioTrack to be observed in a state where
+ // it is released but non null. The only case this might happen
+ // is in the various stopFoo methods that call AudioTrack#stop from
+ // different threads, but they are synchronized on AudioPlayBackHandler#this
+ // too.
+ audioTrack.release();
params.setAudioTrack(null);
- params.getDispatcher().dispatchUtteranceCompleted();
- mLastSynthesisRequest = null;
}
+ params.getDispatcher().dispatchUtteranceCompleted();
+ mLastSynthesisRequest = null;
}
private static void blockUntilDone(SynthesisMessageParams params) {
diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 3bcd266..152827d 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -25,9 +25,9 @@ import java.util.regex.Pattern;
public class Patterns {
/**
* Regular expression to match all IANA top-level domains.
- * List accurate as of 2010/05/06. List taken from:
+ * List accurate as of 2011/07/18. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
+ * This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py
*/
public static final String TOP_LEVEL_DOMAIN_STR =
"((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
@@ -53,7 +53,7 @@ public class Patterns {
+ "|u[agksyz]"
+ "|v[aceginu]"
+ "|w[fs]"
- + "|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-mgbaam7a8h|xn\\-\\-mgberp4a5d4ar|xn\\-\\-wgbh1c|xn\\-\\-zckzah)"
+ + "|(\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)"
+ "|y[et]"
+ "|z[amw])";
@@ -65,9 +65,9 @@ public class Patterns {
/**
* Regular expression to match all IANA top-level domains for WEB_URL.
- * List accurate as of 2010/05/06. List taken from:
+ * List accurate as of 2011/07/18. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
+ * This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py
*/
public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
"(?:"
@@ -94,7 +94,7 @@ public class Patterns {
+ "|u[agksyz]"
+ "|v[aceginu]"
+ "|w[fs]"
- + "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-mgbaam7a8h|xn\\-\\-mgberp4a5d4ar|xn\\-\\-wgbh1c|xn\\-\\-zckzah)"
+ + "|(?:\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)"
+ "|y[et]"
+ "|z[amw]))";
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index bfafa98..e954983 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -23,6 +23,36 @@ package android.view;
* Examples of good action modes include selection modes, search, content editing, etc.
*/
public abstract class ActionMode {
+ private Object mTag;
+
+ /**
+ * Set a tag object associated with this ActionMode.
+ *
+ * <p>Like the tag available to views, this allows applications to associate arbitrary
+ * data with an ActionMode for later reference.
+ *
+ * @param tag Tag to associate with this ActionMode
+ *
+ * @see #getTag()
+ */
+ public void setTag(Object tag) {
+ mTag = tag;
+ }
+
+ /**
+ * Retrieve the tag object associated with this ActionMode.
+ *
+ * <p>Like the tag available to views, this allows applications to associate arbitrary
+ * data with an ActionMode for later reference.
+ *
+ * @return Tag associated with this ActionMode
+ *
+ * @see #setTag(Object)
+ */
+ public Object getTag() {
+ return mTag;
+ }
+
/**
* Set the title of the action mode. This method will have no visible effect if
* a custom view has been set.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4e9c0b7..59cb216 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10756,12 +10756,14 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
// Remember our drawn bit
int drawn = mPrivateFlags & DRAWN;
- // Invalidate our old position
- invalidate(true);
-
-
int oldWidth = mRight - mLeft;
int oldHeight = mBottom - mTop;
+ int newWidth = right - left;
+ int newHeight = bottom - top;
+ boolean sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
+
+ // Invalidate our old position
+ invalidate(sizeChanged);
mLeft = left;
mTop = top;
@@ -10770,10 +10772,8 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
mPrivateFlags |= HAS_BOUNDS;
- int newWidth = right - left;
- int newHeight = bottom - top;
- if (newWidth != oldWidth || newHeight != oldHeight) {
+ if (sizeChanged) {
if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
mMatrixDirty = true;
@@ -10788,7 +10788,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
// before this call to setFrame came in, thereby clearing
// the DRAWN bit.
mPrivateFlags |= DRAWN;
- invalidate(true);
+ invalidate(sizeChanged);
// parent display list may need to be recreated based on a change in the bounds
// of any child
invalidateParentCaches();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5f7673a..5624eb4 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3183,6 +3183,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
+ * @hide
+ */
+ protected void onViewAdded(View child) {
+ if (mOnHierarchyChangeListener != null) {
+ mOnHierarchyChangeListener.onChildViewAdded(this, child);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ protected void onViewRemoved(View child) {
+ if (mOnHierarchyChangeListener != null) {
+ mOnHierarchyChangeListener.onChildViewRemoved(this, child);
+ }
+ }
+
+ /**
* Adds a view during layout. This is useful if in your onLayout() method,
* you need to add more views (as does the list view for example).
*
@@ -3283,9 +3301,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
ai.mKeepScreenOn = lastKeepOn;
}
- if (mOnHierarchyChangeListener != null) {
- mOnHierarchyChangeListener.onChildViewAdded(this, child);
- }
+ onViewAdded(child);
if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) {
mGroupFlags |= FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE;
@@ -3486,9 +3502,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
view.dispatchDetachedFromWindow();
}
- if (mOnHierarchyChangeListener != null) {
- mOnHierarchyChangeListener.onChildViewRemoved(this, view);
- }
+ onViewRemoved(view);
needGlobalAttributesUpdate(false);
@@ -3533,8 +3547,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
private void removeViewsInternal(int start, int count) {
- final OnHierarchyChangeListener onHierarchyChangeListener = mOnHierarchyChangeListener;
- final boolean notifyListener = onHierarchyChangeListener != null;
final View focused = mFocused;
final boolean detach = mAttachInfo != null;
View clearChildFocus = null;
@@ -3563,9 +3575,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
needGlobalAttributesUpdate(false);
- if (notifyListener) {
- onHierarchyChangeListener.onChildViewRemoved(this, view);
- }
+ onViewRemoved(view);
}
removeFromArray(start, count);
@@ -3603,8 +3613,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View[] children = mChildren;
mChildrenCount = 0;
- final OnHierarchyChangeListener listener = mOnHierarchyChangeListener;
- final boolean notify = listener != null;
final View focused = mFocused;
final boolean detach = mAttachInfo != null;
View clearChildFocus = null;
@@ -3630,9 +3638,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
view.dispatchDetachedFromWindow();
}
- if (notify) {
- listener.onChildViewRemoved(this, view);
- }
+ onViewRemoved(view);
view.mParent = null;
children[i] = null;
@@ -3672,9 +3678,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
child.dispatchDetachedFromWindow();
}
- if (mOnHierarchyChangeListener != null) {
- mOnHierarchyChangeListener.onChildViewRemoved(this, child);
- }
+ onViewRemoved(child);
}
/**
@@ -3960,7 +3964,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int left = mLeft;
final int top = mTop;
- if (dirty.intersect(0, 0, mRight - left, mBottom - top) ||
+ if ((mGroupFlags & FLAG_CLIP_CHILDREN) != FLAG_CLIP_CHILDREN ||
+ dirty.intersect(0, 0, mRight - left, mBottom - top) ||
(mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
mPrivateFlags &= ~DRAWING_CACHE_VALID;
@@ -3978,8 +3983,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
location[CHILD_LEFT_INDEX] = mLeft;
location[CHILD_TOP_INDEX] = mTop;
-
- dirty.set(0, 0, mRight - mLeft, mBottom - mTop);
+ if ((mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
+ dirty.set(0, 0, mRight - mLeft, mBottom - mTop);
+ } else {
+ // in case the dirty rect extends outside the bounds of this container
+ dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
+ }
if (mLayerType != LAYER_TYPE_NONE) {
mLocalDirtyRect.union(dirty);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e5f3fc9..da5baf8 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -26,6 +26,7 @@ import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -1580,16 +1581,16 @@ public final class InputMethodManager {
}
/**
- * Set additional input method subtypes.
- * @param imeToken Supplies the identifying token given to an input method.
+ * Set additional input method subtypes. Only a process which shares the same uid with the IME
+ * can add additional input method subtypes to the IME.
+ * @param imiId Id of InputMethodInfo which additional input method subtypes will be added to.
* @param subtypes subtypes will be added as additional subtypes of the current input method.
* @return true if the additional input method subtypes are successfully added.
*/
- public boolean setAdditionalInputMethodSubtypes(
- IBinder imeToken, InputMethodSubtype[] subtypes) {
+ public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
synchronized (mH) {
try {
- return mService.setAdditionalInputMethodSubtypes(imeToken, subtypes);
+ return mService.setAdditionalInputMethodSubtypes(imiId, subtypes);
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
return false;
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 5414b79..d7a2526 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2344,7 +2344,9 @@ public final class WebViewCore {
webViewWidth = mWebView.getViewWidth();
viewportWidth = (int) (webViewWidth / adjust);
if (viewportWidth == 0) {
- Log.w(LOGTAG, "Can't get the viewWidth after the first layout");
+ if (DebugFlags.WEB_VIEW_CORE) {
+ Log.v(LOGTAG, "Can't get the viewWidth yet");
+ }
}
} else {
webViewWidth = Math.round(viewportWidth * mCurrentViewScale);
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 0ffd087..3f5b571 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -16,28 +16,28 @@
package android.widget;
-import com.android.internal.R;
-
import android.annotation.Widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import android.view.SoundEffectConstants;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Transformation;
+import com.android.internal.R;
+
/**
* A view that shows items in a center-locked, horizontally scrolling list.
* <p>
@@ -122,6 +122,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
* in the future. It will also trigger a selection changed.
*/
private Runnable mDisableSuppressSelectionChangedRunnable = new Runnable() {
+ @Override
public void run() {
mSuppressSelectionChanged = false;
selectionChanged();
@@ -171,6 +172,12 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
* drag sends many onScrolls).
*/
private boolean mIsFirstScroll;
+
+ /**
+ * If true, mFirstPosition is the position of the rightmost child, and
+ * the children are ordered right to left.
+ */
+ private boolean mIsRtl = true;
public Gallery(Context context) {
this(context, null);
@@ -418,7 +425,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
}
int getLimitedMotionScrollAmount(boolean motionToLeft, int deltaX) {
- int extremeItemPosition = motionToLeft ? mItemCount - 1 : 0;
+ int extremeItemPosition = motionToLeft != mIsRtl ? mItemCount - 1 : 0;
View extremeChild = getChildAt(extremeItemPosition - mFirstPosition);
if (extremeChild == null) {
@@ -490,31 +497,40 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
if (toLeft) {
final int galleryLeft = mPaddingLeft;
for (int i = 0; i < numChildren; i++) {
- final View child = getChildAt(i);
+ int n = mIsRtl ? (numChildren - 1 - i) : i;
+ final View child = getChildAt(n);
if (child.getRight() >= galleryLeft) {
break;
} else {
+ start = n;
count++;
- mRecycler.put(firstPosition + i, child);
+ mRecycler.put(firstPosition + n, child);
}
}
+ if (!mIsRtl) {
+ start = 0;
+ }
} else {
final int galleryRight = getWidth() - mPaddingRight;
for (int i = numChildren - 1; i >= 0; i--) {
- final View child = getChildAt(i);
+ int n = mIsRtl ? numChildren - 1 - i : i;
+ final View child = getChildAt(n);
if (child.getLeft() <= galleryRight) {
break;
} else {
- start = i;
+ start = n;
count++;
- mRecycler.put(firstPosition + i, child);
+ mRecycler.put(firstPosition + n, child);
}
}
+ if (mIsRtl) {
+ start = 0;
+ }
}
detachViewsFromParent(start, count);
- if (toLeft) {
+ if (toLeft != mIsRtl) {
mFirstPosition += count;
}
}
@@ -614,6 +630,8 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
@Override
void layout(int delta, boolean animate) {
+ mIsRtl = isLayoutRtl();
+
int childrenLeft = mSpinnerPadding.left;
int childrenWidth = mRight - mLeft - mSpinnerPadding.left - mSpinnerPadding.right;
@@ -676,6 +694,45 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
}
private void fillToGalleryLeft() {
+ if (mIsRtl) {
+ fillToGalleryLeftRtl();
+ } else {
+ fillToGalleryLeftLtr();
+ }
+ }
+
+ private void fillToGalleryLeftRtl() {
+ int itemSpacing = mSpacing;
+ int galleryLeft = mPaddingLeft;
+ int numChildren = getChildCount();
+ int numItems = mItemCount;
+
+ // Set state for initial iteration
+ View prevIterationView = getChildAt(numChildren - 1);
+ int curPosition;
+ int curRightEdge;
+
+ if (prevIterationView != null) {
+ curPosition = mFirstPosition + numChildren;
+ curRightEdge = prevIterationView.getLeft() - itemSpacing;
+ } else {
+ // No children available!
+ mFirstPosition = curPosition = mItemCount - 1;
+ curRightEdge = mRight - mLeft - mPaddingRight;
+ mShouldStopFling = true;
+ }
+
+ while (curRightEdge > galleryLeft && curPosition < mItemCount) {
+ prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition,
+ curRightEdge, false);
+
+ // Set state for next iteration
+ curRightEdge = prevIterationView.getLeft() - itemSpacing;
+ curPosition++;
+ }
+ }
+
+ private void fillToGalleryLeftLtr() {
int itemSpacing = mSpacing;
int galleryLeft = mPaddingLeft;
@@ -708,6 +765,45 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
}
private void fillToGalleryRight() {
+ if (mIsRtl) {
+ fillToGalleryRightRtl();
+ } else {
+ fillToGalleryRightLtr();
+ }
+ }
+
+ private void fillToGalleryRightRtl() {
+ int itemSpacing = mSpacing;
+ int galleryRight = mRight - mLeft - mPaddingRight;
+
+ // Set state for initial iteration
+ View prevIterationView = getChildAt(0);
+ int curPosition;
+ int curLeftEdge;
+
+ if (prevIterationView != null) {
+ curPosition = mFirstPosition -1;
+ curLeftEdge = prevIterationView.getRight() + itemSpacing;
+ } else {
+ curPosition = 0;
+ curLeftEdge = mPaddingLeft;
+ mShouldStopFling = true;
+ }
+
+ while (curLeftEdge < galleryRight && curPosition >= 0) {
+ prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition,
+ curLeftEdge, true);
+
+ // Remember some state
+ mFirstPosition = curPosition;
+
+ // Set state for next iteration
+ curLeftEdge = prevIterationView.getRight() + itemSpacing;
+ curPosition--;
+ }
+ }
+
+ private void fillToGalleryRightLtr() {
int itemSpacing = mSpacing;
int galleryRight = mRight - mLeft - mPaddingRight;
int numChildren = getChildCount();
@@ -745,18 +841,16 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
*
* @param position Position in the gallery for the view to obtain
* @param offset Offset from the selected position
- * @param x X-coordintate indicating where this view should be placed. This
+ * @param x X-coordinate indicating where this view should be placed. This
* will either be the left or right edge of the view, depending on
- * the fromLeft paramter
- * @param fromLeft Are we posiitoning views based on the left edge? (i.e.,
+ * the fromLeft parameter
+ * @param fromLeft Are we positioning views based on the left edge? (i.e.,
* building from left to right)?
* @return A view that has been added to the gallery
*/
- private View makeAndAddView(int position, int offset, int x,
- boolean fromLeft) {
+ private View makeAndAddView(int position, int offset, int x, boolean fromLeft) {
View child;
-
if (!mDataChanged) {
child = mRecycler.get(position);
if (child != null) {
@@ -786,27 +880,26 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
/**
* Helper for makeAndAddView to set the position of a view and fill out its
- * layout paramters.
+ * layout parameters.
*
* @param child The view to position
* @param offset Offset from the selected position
- * @param x X-coordintate indicating where this view should be placed. This
+ * @param x X-coordinate indicating where this view should be placed. This
* will either be the left or right edge of the view, depending on
- * the fromLeft paramter
- * @param fromLeft Are we posiitoning views based on the left edge? (i.e.,
+ * the fromLeft parameter
+ * @param fromLeft Are we positioning views based on the left edge? (i.e.,
* building from left to right)?
*/
private void setUpChild(View child, int offset, int x, boolean fromLeft) {
// Respect layout params that are already in the view. Otherwise
// make some up...
- Gallery.LayoutParams lp = (Gallery.LayoutParams)
- child.getLayoutParams();
+ Gallery.LayoutParams lp = (Gallery.LayoutParams) child.getLayoutParams();
if (lp == null) {
lp = (Gallery.LayoutParams) generateDefaultLayoutParams();
}
- addViewInLayout(child, fromLeft ? -1 : 0, lp);
+ addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp);
child.setSelected(offset == 0);
@@ -883,9 +976,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
return retValue;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public boolean onSingleTapUp(MotionEvent e) {
if (mDownTouchPosition >= 0) {
@@ -905,9 +996,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
return false;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (!mShouldCallbackDuringFling) {
@@ -926,9 +1015,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
return true;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (localLOGV) Log.v(TAG, String.valueOf(e2.getX() - e1.getX()));
@@ -967,9 +1054,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
return true;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public boolean onDown(MotionEvent e) {
// Kill any existing fling/scroll
@@ -1009,9 +1094,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
onUp();
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void onLongPress(MotionEvent e) {
if (mDownTouchPosition < 0) {
@@ -1025,9 +1108,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
// Unused methods from GestureDetector.OnGestureListener below
- /**
- * {@inheritDoc}
- */
+ @Override
public void onShowPress(MotionEvent e) {
}
@@ -1164,6 +1245,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
dispatchPress(mSelectedChild);
postDelayed(new Runnable() {
+ @Override
public void run() {
dispatchUnpress();
}
@@ -1278,10 +1360,10 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
// Draw the selected child last
return selectedIndex;
} else if (i >= selectedIndex) {
- // Move the children to the right of the selected child earlier one
+ // Move the children after the selected child earlier one
return i + 1;
} else {
- // Keep the children to the left of the selected child the same
+ // Keep the children before the selected child the same
return i;
}
}
@@ -1306,7 +1388,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
* Responsible for fling behavior. Use {@link #startUsingVelocity(int)} to
* initiate a fling. Each frame of the fling is handled in {@link #run()}.
* A FlingRunnable will keep re-posting itself until the fling is done.
- *
*/
private class FlingRunnable implements Runnable {
/**
@@ -1365,6 +1446,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
if (scrollIntoSlots) scrollIntoSlots();
}
+ @Override
public void run() {
if (mItemCount == 0) {
@@ -1384,15 +1466,17 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
// Pretend that each frame of a fling scroll is a touch scroll
if (delta > 0) {
- // Moving towards the left. Use first view as mDownTouchPosition
- mDownTouchPosition = mFirstPosition;
+ // Moving towards the left. Use leftmost view as mDownTouchPosition
+ mDownTouchPosition = mIsRtl ? (mFirstPosition + getChildCount() - 1) :
+ mFirstPosition;
// Don't fling more than 1 screen
delta = Math.min(getWidth() - mPaddingLeft - mPaddingRight - 1, delta);
} else {
- // Moving towards the right. Use last view as mDownTouchPosition
+ // Moving towards the right. Use rightmost view as mDownTouchPosition
int offsetToLast = getChildCount() - 1;
- mDownTouchPosition = mFirstPosition + offsetToLast;
+ mDownTouchPosition = mIsRtl ? mFirstPosition :
+ (mFirstPosition + getChildCount() - 1);
// Don't fling more than 1 screen
delta = Math.max(-(getWidth() - mPaddingRight - mPaddingLeft - 1), delta);
@@ -1414,7 +1498,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList
* Gallery extends LayoutParams to provide a place to hold current
* Transformation information along with previous position/transformation
* info.
- *
*/
public static class LayoutParams extends ViewGroup.LayoutParams {
public LayoutParams(Context c, AttributeSet attrs) {
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index f82c61a..46fe407 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -757,39 +757,21 @@ public class GridLayout extends ViewGroup {
// Add/remove
+ /**
+ * @hide
+ */
@Override
- public void addView(View child, int index, ViewGroup.LayoutParams params) {
- super.addView(child, index, params);
- invalidateStructure();
- }
-
- @Override
- public void removeView(View view) {
- super.removeView(view);
- invalidateStructure();
- }
-
- @Override
- public void removeViewInLayout(View view) {
- super.removeViewInLayout(view);
- invalidateStructure();
- }
-
- @Override
- public void removeViewsInLayout(int start, int count) {
- super.removeViewsInLayout(start, count);
- invalidateStructure();
- }
-
- @Override
- public void removeViewAt(int index) {
- super.removeViewAt(index);
+ protected void onViewAdded(View child) {
+ super.onViewAdded(child);
invalidateStructure();
}
+ /**
+ * @hide
+ */
@Override
- public void removeAllViews() {
- super.removeAllViews();
+ protected void onViewRemoved(View child) {
+ super.onViewRemoved(child);
invalidateStructure();
}
@@ -2301,25 +2283,6 @@ public class GridLayout extends ViewGroup {
}
/**
- * Temporary backward compatibility class for Launcher - to avoid
- * dependent multi-project commit. This class will be deleted after
- * AppsCustomizePagedView is updated to new API.
- *
- * @hide
- */
- @Deprecated
- public static class Group extends Spec {
- /**
- * @deprecated Please replace with {@link #spec(int, int, Alignment)}
- * @hide
- */
- @Deprecated
- public Group(int start, int size, Alignment alignment) {
- super(start, size, alignment, UNDEFINED_FLEXIBILITY);
- }
- }
-
- /**
* Return a Spec, {@code spec}, where:
* <ul>
* <li> {@code spec.span = [start, start + size]} </li>
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index f3bda43..b2d1a1e 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -18,8 +18,6 @@ package android.widget;
import static android.widget.SuggestionsAdapter.getColumnString;
-import com.android.internal.R;
-
import android.app.PendingIntent;
import android.app.SearchManager;
import android.app.SearchableInfo;
@@ -39,10 +37,14 @@ import android.net.Uri;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
+import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -51,6 +53,8 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.TextView.OnEditorActionListener;
+import com.android.internal.R;
+
import java.util.WeakHashMap;
/**
@@ -87,6 +91,8 @@ public class SearchView extends LinearLayout {
private View mSearchEditFrame;
private View mVoiceButton;
private SearchAutoComplete mQueryTextView;
+ private View mDropDownAnchor;
+ private ImageView mSearchHintIcon;
private boolean mSubmitButtonEnabled;
private CharSequence mQueryHint;
private boolean mQueryRefinement;
@@ -195,6 +201,7 @@ public class SearchView extends LinearLayout {
mSubmitButton = findViewById(R.id.search_go_btn);
mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
mVoiceButton = findViewById(R.id.search_voice_btn);
+ mSearchHintIcon = (ImageView) findViewById(R.id.search_mag_icon);
mSearchButton.setOnClickListener(mOnClickListener);
mCloseButton.setOnClickListener(mOnClickListener);
@@ -244,7 +251,20 @@ public class SearchView extends LinearLayout {
mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mDropDownAnchor = findViewById(mQueryTextView.getDropDownAnchor());
+ if (mDropDownAnchor != null) {
+ mDropDownAnchor.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ adjustDropDownSizeAndPosition();
+ }
+
+ });
+ }
+
updateViewsVisibility(mIconifiedByDefault);
+ updateQueryHint();
}
/**
@@ -263,7 +283,7 @@ public class SearchView extends LinearLayout {
}
// Cache the voice search capability
mVoiceButtonEnabled = hasVoiceSearch();
- updateViewsVisibility(mIconifiedByDefault);
+ updateViewsVisibility(isIconified());
}
/**
@@ -300,7 +320,6 @@ public class SearchView extends LinearLayout {
mQueryTextView.clearFocus();
setImeVisibility(false);
mClearingFocus = false;
- updateViewsVisibility(mIconifiedByDefault);
}
/**
@@ -555,6 +574,7 @@ public class SearchView extends LinearLayout {
mSearchButton.setVisibility(visCollapsed);
updateSubmitButton(hasText);
mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE);
+ mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE);
updateCloseButton();
updateVoiceButton(!hasText);
updateSubmitArea();
@@ -822,9 +842,29 @@ public class SearchView extends LinearLayout {
return result;
}
+ private int getSearchIconId() {
+ TypedValue outValue = new TypedValue();
+ getContext().getTheme().resolveAttribute(com.android.internal.R.attr.searchViewSearchIcon,
+ outValue, true);
+ return outValue.resourceId;
+ }
+
+ private CharSequence getDecoratedHint(CharSequence hintText) {
+ // If the field is always expanded, then don't add the search icon to the hint
+ if (!mIconifiedByDefault) return hintText;
+
+ SpannableStringBuilder ssb = new SpannableStringBuilder(" "); // for the icon
+ ssb.append(hintText);
+ Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId());
+ int textSize = (int) (mQueryTextView.getTextSize() * 1.25);
+ searchIcon.setBounds(0, 0, textSize, textSize);
+ ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return ssb;
+ }
+
private void updateQueryHint() {
if (mQueryHint != null) {
- mQueryTextView.setHint(mQueryHint);
+ mQueryTextView.setHint(getDecoratedHint(mQueryHint));
} else if (mSearchable != null) {
CharSequence hint = null;
int hintId = mSearchable.getHintId();
@@ -832,8 +872,10 @@ public class SearchView extends LinearLayout {
hint = getContext().getString(hintId);
}
if (hint != null) {
- mQueryTextView.setHint(hint);
+ mQueryTextView.setHint(getDecoratedHint(hint));
}
+ } else {
+ mQueryTextView.setHint(getDecoratedHint(""));
}
}
@@ -922,9 +964,13 @@ public class SearchView extends LinearLayout {
CharSequence text = mQueryTextView.getText();
if (TextUtils.isEmpty(text)) {
if (mIconifiedByDefault) {
- // query field already empty, hide the keyboard and remove focus
- clearFocus();
- setImeVisibility(false);
+ // If the app doesn't override the close behavior
+ if (mOnCloseListener == null || !mOnCloseListener.onClose()) {
+ // hide the keyboard and remove focus
+ clearFocus();
+ // collapse the search field
+ updateViewsVisibility(true);
+ }
}
} else {
mQueryTextView.setText("");
@@ -932,10 +978,6 @@ public class SearchView extends LinearLayout {
setImeVisibility(true);
}
- if (mIconifiedByDefault && (mOnCloseListener == null || !mOnCloseListener.onClose())) {
- updateViewsVisibility(mIconifiedByDefault);
- setImeVisibility(false);
- }
}
private void onSearchClicked() {
@@ -975,6 +1017,28 @@ public class SearchView extends LinearLayout {
updateFocusedState(mQueryTextView.hasFocus());
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ }
+
+ private void adjustDropDownSizeAndPosition() {
+ if (mDropDownAnchor.getWidth() > 1) {
+ Resources res = getContext().getResources();
+ int anchorPadding = mSearchPlate.getPaddingLeft();
+ Rect dropDownPadding = new Rect();
+ int iconOffset = mIconifiedByDefault
+ ? res.getDimensionPixelSize(R.dimen.dropdownitem_icon_width)
+ + res.getDimensionPixelSize(R.dimen.dropdownitem_text_padding_left)
+ : 0;
+ mQueryTextView.getDropDownBackground().getPadding(dropDownPadding);
+ mQueryTextView.setDropDownHorizontalOffset(-(dropDownPadding.left + iconOffset)
+ + anchorPadding);
+ mQueryTextView.setDropDownWidth(mDropDownAnchor.getWidth() + dropDownPadding.left
+ + dropDownPadding.right + iconOffset - (anchorPadding));
+ }
+ }
+
private boolean onItemClicked(int position, int actionKey, String actionMsg) {
if (mOnSuggestionListener == null
|| !mOnSuggestionListener.onSuggestionClick(position)) {
@@ -1393,5 +1457,32 @@ public class SearchView extends LinearLayout {
public boolean enoughToFilter() {
return mThreshold <= 0 || super.enoughToFilter();
}
+
+ @Override
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ // special case for the back key, we do not even try to send it
+ // to the drop down list but instead, consume it immediately
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.handleUpEvent(event);
+ }
+ if (event.isTracking() && !event.isCanceled()) {
+ mSearchView.clearFocus();
+ mSearchView.setImeVisibility(false);
+ return true;
+ }
+ }
+ }
+ return super.onKeyPreIme(keyCode, event);
+ }
+
}
}
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index 2cfc016..9e32c9a 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -16,8 +16,6 @@
package android.widget;
-import com.android.internal.R;
-
import android.app.SearchDialog;
import android.app.SearchManager;
import android.app.SearchableInfo;
@@ -47,6 +45,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
+import com.android.internal.R;
+
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -88,8 +88,8 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
private int mIconName2Col = INVALID_INDEX;
private int mFlagsCol = INVALID_INDEX;
- private final Runnable mStartSpinnerRunnable;
- private final Runnable mStopSpinnerRunnable;
+ // private final Runnable mStartSpinnerRunnable;
+ // private final Runnable mStopSpinnerRunnable;
/**
* The amount of time we delay in the filter when the user presses the delete key.
@@ -113,17 +113,18 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
mOutsideDrawablesCache = outsideDrawablesCache;
- mStartSpinnerRunnable = new Runnable() {
- public void run() {
- // mSearchView.setWorking(true); // TODO:
- }
- };
- mStopSpinnerRunnable = new Runnable() {
- public void run() {
- // mSearchView.setWorking(false); // TODO:
- }
- };
+ // mStartSpinnerRunnable = new Runnable() {
+ // public void run() {
+ // // mSearchView.setWorking(true); // TODO:
+ // }
+ // };
+ //
+ // mStopSpinnerRunnable = new Runnable() {
+ // public void run() {
+ // // mSearchView.setWorking(false); // TODO:
+ // }
+ // };
// delay 500ms when deleting
getFilter().setDelayer(new Filter.Delayer() {
@@ -341,10 +342,10 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
}
if (views.mIcon1 != null) {
- setViewDrawable(views.mIcon1, getIcon1(cursor));
+ setViewDrawable(views.mIcon1, getIcon1(cursor), View.INVISIBLE);
}
if (views.mIcon2 != null) {
- setViewDrawable(views.mIcon2, getIcon2(cursor));
+ setViewDrawable(views.mIcon2, getIcon2(cursor), View.GONE);
}
if (mQueryRefinement == REFINE_ALL
|| (mQueryRefinement == REFINE_BY_ENTRY
@@ -414,13 +415,13 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene
* Sets the drawable in an image view, makes sure the view is only visible if there
* is a drawable.
*/
- private void setViewDrawable(ImageView v, Drawable drawable) {
+ private void setViewDrawable(ImageView v, Drawable drawable, int nullVisibility) {
// Set the icon even if the drawable is null, since we need to clear any
// previous icon.
v.setImageDrawable(drawable);
if (drawable == null) {
- v.setVisibility(View.GONE);
+ v.setVisibility(nullVisibility);
} else {
v.setVisibility(View.VISIBLE);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 812f92b..ce0299c 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -68,5 +68,5 @@ interface IInputMethodManager {
boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);
boolean switchToLastInputMethod(in IBinder token);
boolean setInputMethodEnabled(String id, boolean enabled);
- boolean setAdditionalInputMethodSubtypes(in IBinder token, in InputMethodSubtype[] subtypes);
+ boolean setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 6a13876..30fe298 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -323,9 +323,7 @@ size_t TextLayoutCacheValue::getSize() {
void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
- size_t contextCount, int dirFlags) {
- bool isRTL = dirFlags & 0x1;
-
+ size_t contextCount, bool isRTL) {
font->klass = &harfbuzzSkiaClass;
font->userData = 0;
// The values which harfbuzzSkiaClass returns are already scaled to
@@ -374,10 +372,10 @@ void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec
void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font,
FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
- size_t contextCount, int dirFlags) {
+ size_t contextCount, bool isRTL) {
// Setup Harfbuzz Shaper
setupShaperItem(shaperItem, font, fontData, paint, chars, start, count,
- contextCount, dirFlags);
+ contextCount, isRTL);
// Shape
resetGlyphArrays(shaperItem);
@@ -430,7 +428,7 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
forceLTR, forceRTL);
#endif
- computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+ computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, forceRTL,
outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
if (forceRTL && *outGlyphsCount > 1) {
@@ -451,10 +449,15 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", dirFlags, rc, paraDir);
#endif
if (rc == 1 || !U_SUCCESS(status)) {
+ bool isRTL = (paraDir == 1);
+#if DEBUG_GLYPHS
+ LOGD("computeValuesWithHarfbuzz -- processing SINGLE run "
+ "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
+#endif
computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount,
- dirFlags, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
+ isRTL, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
- if (dirFlags == 1 && *outGlyphsCount > 1) {
+ if (isRTL && *outGlyphsCount > 1) {
reverseGlyphArray(*outGlyphs, *outGlyphsCount);
}
} else {
@@ -485,14 +488,14 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
lengthRun = endRun - startRun;
- int newFlags = (runDir == UBIDI_RTL) ? kDirection_RTL : kDirection_LTR;
+ bool isRTL = (runDir == UBIDI_RTL);
jfloat runTotalAdvance = 0;
#if DEBUG_GLYPHS
- LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d newFlags=%d",
- startRun, lengthRun, newFlags);
+ LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
+ startRun, lengthRun, isRTL);
#endif
computeRunValuesWithHarfbuzz(paint, chars, startRun,
- lengthRun, contextCount, newFlags,
+ lengthRun, contextCount, isRTL,
outAdvances, &runTotalAdvance,
&runGlyphs, &runGlyphsCount);
@@ -506,7 +509,7 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
LOGD(" -- glyphs[%d]=%d", j, runGlyphs[j]);
}
#endif
- glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, newFlags));
+ glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, isRTL));
}
*outGlyphs = new jchar[*outGlyphsCount];
@@ -528,13 +531,15 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
ubidi_close(bidi);
} else {
// Cannot run BiDi, just consider one Run
+ bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
#if DEBUG_GLYPHS
- LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering only one Run");
+ LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
+ "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
#endif
- computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+ computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, isRTL,
outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
- if (dirFlags == 1 && *outGlyphsCount > 1) {
+ if (isRTL && *outGlyphsCount > 1) {
reverseGlyphArray(*outGlyphs, *outGlyphsCount);
}
}
@@ -545,17 +550,15 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
}
void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
- size_t start, size_t count, size_t contextCount, int dirFlags,
+ size_t start, size_t count, size_t contextCount, bool isRTL,
jfloat* outAdvances, jfloat* outTotalAdvance,
jchar** outGlyphs, size_t* outGlyphsCount) {
- bool isRTL = dirFlags & 0x1;
-
HB_ShaperItem shaperItem;
HB_FontRec font;
FontData fontData;
shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
- contextCount, dirFlags);
+ contextCount, isRTL);
#if DEBUG_GLYPHS
LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 690caac..10dee87 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -128,11 +128,11 @@ public:
static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
- int dirFlags);
+ bool isRTL);
static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
- int dirFlags);
+ bool isRTL);
static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
size_t count, size_t contextCount, int dirFlags,
@@ -179,7 +179,7 @@ private:
static void resetGlyphArrays(HB_ShaperItem* shaperItem);
static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
- size_t count, size_t contextCount, int dirFlags,
+ size_t count, size_t contextCount, bool isRTL,
jfloat* outAdvances, jfloat* outTotalAdvance,
jchar** outGlyphs, size_t* outGlyphsCount);
}; // TextLayoutCacheValue
diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml
index 790ac6b..f6b5b53 100644
--- a/core/res/res/layout/search_bar.xml
+++ b/core/res/res/layout/search_bar.xml
@@ -66,7 +66,6 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxWidth="600dip"
- android:iconifiedByDefault="false"
android:layout_gravity="center_vertical"
/>
diff --git a/core/res/res/layout/search_dropdown_item_icons_2line.xml b/core/res/res/layout/search_dropdown_item_icons_2line.xml
index 53906f9..acef2cc 100644
--- a/core/res/res/layout/search_dropdown_item_icons_2line.xml
+++ b/core/res/res/layout/search_dropdown_item_icons_2line.xml
@@ -19,21 +19,21 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:paddingLeft="4dip"
- android:paddingRight="2dip"
+ android:paddingLeft="@dimen/dropdownitem_text_padding_left"
+ android:paddingRight="4dip"
android:layout_width="match_parent"
android:layout_height="?android:attr/searchResultListItemHeight" >
<!-- Icons come first in the layout, since their placement doesn't depend on
the placement of the text views. -->
<ImageView android:id="@android:id/icon1"
- android:layout_width="48dip"
+ android:layout_width="@dimen/dropdownitem_icon_width"
android:layout_height="48dip"
android:scaleType="centerInside"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
- android:visibility="gone" />
+ android:visibility="invisible" />
<ImageView android:id="@+id/edit_query"
android:layout_width="48dip"
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index fee27eb..6b70d8d 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -22,6 +22,8 @@
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
android:orientation="horizontal"
>
@@ -30,7 +32,7 @@
android:id="@+id/search_badge"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
+ android:gravity="center_vertical"
android:layout_marginBottom="2dip"
android:drawablePadding="0dip"
android:textAppearance="?android:attr/textAppearanceMedium"
@@ -54,12 +56,21 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
android:layout_marginTop="4dip"
android:layout_marginBottom="4dip"
android:orientation="horizontal">
+ <ImageView
+ android:id="@+id/search_mag_icon"
+ android:layout_width="@dimen/dropdownitem_icon_width"
+ android:layout_height="wrap_content"
+ android:scaleType="centerInside"
+ android:layout_marginLeft="@dimen/dropdownitem_text_padding_left"
+ android:layout_gravity="center_vertical"
+ android:src="?android:attr/searchViewSearchIcon"
+ android:visibility="gone"
+ />
+
<!-- Inner layout contains the app icon, button(s) and EditText -->
<LinearLayout
android:id="@+id/search_plate"
@@ -70,14 +81,6 @@
android:orientation="horizontal"
android:background="?android:attr/searchViewTextField">
- <ImageView
- android:id="@+id/search_app_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:src="?android:attr/searchViewSearchIcon"
- />
-
<view class="android.widget.SearchView$SearchAutoComplete"
android:id="@+id/search_src_text"
android:layout_height="36dip"
@@ -85,8 +88,8 @@
android:layout_weight="1"
android:minWidth="@dimen/search_view_text_min_width"
android:layout_gravity="bottom"
- android:paddingLeft="8dip"
- android:paddingRight="6dip"
+ android:paddingLeft="@dimen/dropdownitem_text_padding_left"
+ android:paddingRight="@dimen/dropdownitem_text_padding_right"
android:singleLine="true"
android:ellipsize="end"
android:background="@null"
@@ -100,7 +103,7 @@
<ImageView
android:id="@+id/search_close_btn"
- android:layout_width="wrap_content"
+ android:layout_width="@dimen/dropdownitem_icon_width"
android:layout_height="match_parent"
android:paddingLeft="8dip"
android:paddingRight="8dip"
@@ -131,7 +134,7 @@
android:visibility="gone"
android:focusable="true"
/>
-
+
<ImageView
android:id="@+id/search_voice_btn"
android:layout_width="wrap_content"
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 7aabf80..0ed8076 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -141,4 +141,13 @@
<!-- The default gap between components in a layout. -->
<dimen name="default_gap">16dip</dimen>
+ <!-- Text padding for dropdown items -->
+ <dimen name="dropdownitem_text_padding_left">6dip</dimen>
+
+ <!-- Text padding for dropdown items -->
+ <dimen name="dropdownitem_text_padding_right">6dip</dimen>
+
+ <!-- Width of the icon in a dropdown list -->
+ <dimen name="dropdownitem_icon_width">48dip</dimen>
+
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5b5e7c3..d647467 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -563,8 +563,8 @@
<style name="Widget.DropDownItem">
<item name="android:textAppearance">@style/TextAppearance.Widget.DropDownItem</item>
- <item name="android:paddingLeft">6dip</item>
- <item name="android:paddingRight">6dip</item>
+ <item name="android:paddingLeft">@dimen/dropdownitem_text_padding_left</item>
+ <item name="android:paddingRight">@dimen/dropdownitem_text_padding_right</item>
<item name="android:gravity">center_vertical</item>
</style>
diff --git a/core/tests/coretests/src/android/database/MatrixCursorTest.java b/core/tests/coretests/src/android/database/MatrixCursorTest.java
index cddc6c4..cdab638 100644
--- a/core/tests/coretests/src/android/database/MatrixCursorTest.java
+++ b/core/tests/coretests/src/android/database/MatrixCursorTest.java
@@ -16,6 +16,8 @@
package android.database;
+import android.test.MoreAsserts;
+
import junit.framework.TestCase;
import java.util.*;
@@ -33,6 +35,7 @@ public class MatrixCursorTest extends TestCase {
cursor.moveToNext();
assertTrue(cursor.isNull(0));
assertNull(cursor.getString(0));
+ assertNull(cursor.getBlob(0));
assertEquals(0, cursor.getShort(0));
assertEquals(0, cursor.getInt(0));
assertEquals(0L, cursor.getLong(0));
@@ -49,7 +52,8 @@ public class MatrixCursorTest extends TestCase {
.add(2)
.add(3)
.add(4)
- .add(5);
+ .add(5)
+ .add(new byte[] {(byte) 0xaa, (byte) 0x55});
cursor.moveToNext();
@@ -61,7 +65,8 @@ public class MatrixCursorTest extends TestCase {
.add("2")
.add("3")
.add("4")
- .add("5");
+ .add("5")
+ .add(new byte[] {(byte) 0xaa, (byte) 0x55});
cursor.moveToNext();
checkValues(cursor);
@@ -73,7 +78,7 @@ public class MatrixCursorTest extends TestCase {
public void testAddArray() {
MatrixCursor cursor = newMatrixCursor();
- cursor.addRow(new Object[] { "a", 1, 2, 3, 4, 5 });
+ cursor.addRow(new Object[] { "a", 1, 2, 3, 4, 5, new byte[] {(byte) 0xaa, (byte) 0x55} });
cursor.moveToNext();
checkValues(cursor);
@@ -86,7 +91,7 @@ public class MatrixCursorTest extends TestCase {
public void testAddIterable() {
MatrixCursor cursor = newMatrixCursor();
- cursor.addRow(Arrays.asList("a", 1, 2, 3, 4, 5));
+ cursor.addRow(Arrays.asList("a", 1, 2, 3, 4, 5, new byte[] {(byte) 0xaa, (byte) 0x55}));
cursor.moveToNext();
checkValues(cursor);
@@ -96,7 +101,8 @@ public class MatrixCursorTest extends TestCase {
} catch (IllegalArgumentException e) { /* expected */ }
try {
- cursor.addRow(Arrays.asList("a", 1, 2, 3, 4, 5, "Too many!"));
+ cursor.addRow(Arrays.asList("a", 1, 2, 3, 4, 5,
+ new byte[] {(byte) 0xaa, (byte) 0x55}, "Too many!"));
fail();
} catch (IllegalArgumentException e) { /* expected */ }
}
@@ -105,7 +111,7 @@ public class MatrixCursorTest extends TestCase {
MatrixCursor cursor = newMatrixCursor();
cursor.addRow(new NonIterableArrayList<Object>(
- Arrays.asList("a", 1, 2, 3, 4, 5)));
+ Arrays.asList("a", 1, 2, 3, 4, 5, new byte[] {(byte) 0xaa, (byte) 0x55})));
cursor.moveToNext();
checkValues(cursor);
@@ -116,7 +122,8 @@ public class MatrixCursorTest extends TestCase {
try {
cursor.addRow(new NonIterableArrayList<Object>(
- Arrays.asList("a", 1, 2, 3, 4, 5, "Too many!")));
+ Arrays.asList("a", 1, 2, 3, 4, 5,
+ new byte[] {(byte) 0xaa, (byte) 0x55}, "Too many!")));
fail();
} catch (IllegalArgumentException e) { /* expected */ }
}
@@ -137,7 +144,7 @@ public class MatrixCursorTest extends TestCase {
private MatrixCursor newMatrixCursor() {
return new MatrixCursor(new String[] {
- "string", "short", "int", "long", "float", "double" });
+ "string", "short", "int", "long", "float", "double", "blob" });
}
private void checkValues(MatrixCursor cursor) {
@@ -147,6 +154,7 @@ public class MatrixCursorTest extends TestCase {
assertEquals(3, cursor.getLong(3));
assertEquals(4.0f, cursor.getFloat(4));
assertEquals(5.0D, cursor.getDouble(5));
+ MoreAsserts.assertEquals(new byte[] {(byte) 0xaa, (byte) 0x55}, cursor.getBlob(6));
}
}
diff --git a/core/tests/coretests/src/android/util/JsonReaderTest.java b/core/tests/coretests/src/android/util/JsonReaderTest.java
index 440aeb5..0b50af3 100644
--- a/core/tests/coretests/src/android/util/JsonReaderTest.java
+++ b/core/tests/coretests/src/android/util/JsonReaderTest.java
@@ -858,7 +858,7 @@ public final class JsonReaderTest extends TestCase {
}
public void testFailWithPosition() throws IOException {
- testFailWithPosition("Expected literal value at line 6 column 3",
+ testFailWithPosition("Expected literal value at line 6 column 3",
"[\n\n\n\n\n0,}]");
}
diff --git a/core/tests/coretests/src/android/util/PatternsTest.java b/core/tests/coretests/src/android/util/PatternsTest.java
index aad3fe1..9519b9f 100644
--- a/core/tests/coretests/src/android/util/PatternsTest.java
+++ b/core/tests/coretests/src/android/util/PatternsTest.java
@@ -39,6 +39,10 @@ public class PatternsTest extends TestCase {
t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn--0zwm56d").matches();
assertTrue("Missed valid TLD", t);
+ // One of the new top level internationalized domain.
+ t = Patterns.TOP_LEVEL_DOMAIN.matcher("\uD55C\uAD6D").matches();
+ assertTrue("Missed valid TLD", t);
+
t = Patterns.TOP_LEVEL_DOMAIN.matcher("mem").matches();
assertFalse("Matched invalid TLD!", t);
@@ -80,6 +84,9 @@ public class PatternsTest extends TestCase {
assertTrue("Valid URL", t);
t = Patterns.WEB_URL.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
assertTrue("Valid URL", t);
+ // URL with international TLD.
+ t = Patterns.WEB_URL.matcher("\uB3C4\uBA54\uC778.\uD55C\uAD6D").matches();
+ assertTrue("Valid URL", t);
t = Patterns.WEB_URL.matcher("http://brainstormtech.blogs.fortune.cnn.com/2010/03/11/" +
"top-five-moments-from-eric-schmidt\u2019s-talk-in-abu-dhabi/").matches();