summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rwxr-xr-xcore/java/android/content/res/Resources.java51
-rw-r--r--core/java/android/net/nsd/DnsSdServiceInfo.java47
-rw-r--r--core/java/android/net/nsd/NsdManager.java50
-rw-r--r--core/java/android/provider/BrowserContract.java191
-rw-r--r--core/java/android/provider/ContactsContract.java8
-rw-r--r--core/java/android/text/SpannableStringBuilder.java220
-rw-r--r--core/java/android/view/TextureView.java4
-rw-r--r--core/java/android/webkit/WebViewClassic.java117
-rw-r--r--core/java/android/widget/NumberPicker.java11
-rw-r--r--core/java/android/widget/Switch.java11
10 files changed, 552 insertions, 158 deletions
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 2af58be..c682852 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -32,7 +32,6 @@ import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Slog;
-import android.util.SparseArray;
import android.util.TypedValue;
import android.util.LongSparseArray;
@@ -86,8 +85,8 @@ public class Resources {
// single-threaded, and after that these are immutable.
private static final LongSparseArray<Drawable.ConstantState> sPreloadedDrawables
= new LongSparseArray<Drawable.ConstantState>();
- private static final SparseArray<ColorStateList> mPreloadedColorStateLists
- = new SparseArray<ColorStateList>();
+ private static final LongSparseArray<ColorStateList> sPreloadedColorStateLists
+ = new LongSparseArray<ColorStateList>();
private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
= new LongSparseArray<Drawable.ConstantState>();
private static boolean mPreloaded;
@@ -98,8 +97,8 @@ public class Resources {
// These are protected by the mTmpValue lock.
private final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache
= new LongSparseArray<WeakReference<Drawable.ConstantState> >();
- private final SparseArray<WeakReference<ColorStateList> > mColorStateListCache
- = new SparseArray<WeakReference<ColorStateList> >();
+ private final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache
+ = new LongSparseArray<WeakReference<ColorStateList> >();
private final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
= new LongSparseArray<WeakReference<Drawable.ConstantState> >();
private boolean mPreloading;
@@ -118,22 +117,6 @@ public class Resources {
private CompatibilityInfo mCompatibilityInfo;
- private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>(0) {
- @Override
- public void put(long k, Object o) {
- throw new UnsupportedOperationException();
- }
- @Override
- public void append(long k, Object o) {
- throw new UnsupportedOperationException();
- }
- };
-
- @SuppressWarnings("unchecked")
- private static <T> LongSparseArray<T> emptySparseArray() {
- return (LongSparseArray<T>) EMPTY_ARRAY;
- }
-
/** @hide */
public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
return selectSystemTheme(curTheme, targetSdkVersion,
@@ -180,9 +163,8 @@ public class Resources {
* @param config Desired device configuration to consider when
* selecting/computing resource values (optional).
*/
- public Resources(AssetManager assets, DisplayMetrics metrics,
- Configuration config) {
- this(assets, metrics, config, (CompatibilityInfo) null);
+ public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
+ this(assets, metrics, config, null);
}
/**
@@ -1883,7 +1865,8 @@ public class Resources {
return dr;
}
- Drawable.ConstantState cs = isColorDrawable ? sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key);
+ Drawable.ConstantState cs = isColorDrawable ?
+ sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key);
if (cs != null) {
dr = cs.newDrawable(this);
} else {
@@ -2005,21 +1988,21 @@ public class Resources {
}
}
- final int key = (value.assetCookie << 24) | value.data;
+ final long key = (((long) value.assetCookie) << 32) | value.data;
ColorStateList csl;
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
- csl = mPreloadedColorStateLists.get(key);
+ csl = sPreloadedColorStateLists.get(key);
if (csl != null) {
return csl;
}
csl = ColorStateList.valueOf(value.data);
if (mPreloading) {
- mPreloadedColorStateLists.put(key, csl);
+ sPreloadedColorStateLists.put(key, csl);
}
return csl;
@@ -2030,7 +2013,7 @@ public class Resources {
return csl;
}
- csl = mPreloadedColorStateLists.get(key);
+ csl = sPreloadedColorStateLists.get(key);
if (csl != null) {
return csl;
}
@@ -2063,14 +2046,13 @@ public class Resources {
if (csl != null) {
if (mPreloading) {
- mPreloadedColorStateLists.put(key, csl);
+ sPreloadedColorStateLists.put(key, csl);
} else {
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached color state list @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + csl);
- mColorStateListCache.put(
- key, new WeakReference<ColorStateList>(csl));
+ mColorStateListCache.put(key, new WeakReference<ColorStateList>(csl));
}
}
}
@@ -2078,7 +2060,7 @@ public class Resources {
return csl;
}
- private ColorStateList getCachedColorStateList(int key) {
+ private ColorStateList getCachedColorStateList(long key) {
synchronized (mTmpValue) {
WeakReference<ColorStateList> wr = mColorStateListCache.get(key);
if (wr != null) { // we have the key
@@ -2088,8 +2070,7 @@ public class Resources {
// Integer.toHexString(((Integer)key).intValue())
// + " in " + this + ": " + entry);
return entry;
- }
- else { // our entry has been purged
+ } else { // our entry has been purged
mColorStateListCache.delete(key);
}
}
diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/DnsSdServiceInfo.java
index 47d6ec6..33c3eb9 100644
--- a/core/java/android/net/nsd/DnsSdServiceInfo.java
+++ b/core/java/android/net/nsd/DnsSdServiceInfo.java
@@ -19,6 +19,8 @@ package android.net.nsd;
import android.os.Parcelable;
import android.os.Parcel;
+import java.net.InetAddress;
+
/**
* Defines a service based on DNS service discovery
* {@hide}
@@ -27,20 +29,20 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
private String mServiceName;
- private String mRegistrationType;
+ private String mServiceType;
private DnsSdTxtRecord mTxtRecord;
- private String mHostname;
+ private InetAddress mHost;
private int mPort;
- DnsSdServiceInfo() {
+ public DnsSdServiceInfo() {
}
- DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
+ public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
mServiceName = sn;
- mRegistrationType = rt;
+ mServiceType = rt;
mTxtRecord = tr;
}
@@ -59,13 +61,13 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
@Override
/** @hide */
public String getServiceType() {
- return mRegistrationType;
+ return mServiceType;
}
@Override
/** @hide */
public void setServiceType(String s) {
- mRegistrationType = s;
+ mServiceType = s;
}
public DnsSdTxtRecord getTxtRecord() {
@@ -76,12 +78,12 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
mTxtRecord = new DnsSdTxtRecord(t);
}
- public String getHostName() {
- return mHostname;
+ public InetAddress getHost() {
+ return mHost;
}
- public void setHostName(String s) {
- mHostname = s;
+ public void setHost(InetAddress s) {
+ mHost = s;
}
public int getPort() {
@@ -96,7 +98,9 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
StringBuffer sb = new StringBuffer();
sb.append("name: ").append(mServiceName).
- append("type: ").append(mRegistrationType).
+ append("type: ").append(mServiceType).
+ append("host: ").append(mHost).
+ append("port: ").append(mPort).
append("txtRecord: ").append(mTxtRecord);
return sb.toString();
}
@@ -109,9 +113,14 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
/** Implement the Parcelable interface */
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mServiceName);
- dest.writeString(mRegistrationType);
+ dest.writeString(mServiceType);
dest.writeParcelable(mTxtRecord, flags);
- dest.writeString(mHostname);
+ if (mHost != null) {
+ dest.writeByte((byte)1);
+ dest.writeByteArray(mHost.getAddress());
+ } else {
+ dest.writeByte((byte)0);
+ }
dest.writeInt(mPort);
}
@@ -121,9 +130,15 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
public DnsSdServiceInfo createFromParcel(Parcel in) {
DnsSdServiceInfo info = new DnsSdServiceInfo();
info.mServiceName = in.readString();
- info.mRegistrationType = in.readString();
+ info.mServiceType = in.readString();
info.mTxtRecord = in.readParcelable(null);
- info.mHostname = in.readString();
+
+ if (in.readByte() == 1) {
+ try {
+ info.mHost = InetAddress.getByAddress(in.createByteArray());
+ } catch (java.net.UnknownHostException e) {}
+ }
+
info.mPort = in.readInt();
return info;
}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index a109a98..505f11b 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -93,6 +93,15 @@ public class NsdManager {
/** @hide */
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 17;
+ /** @hide */
+ public static final int STOP_RESOLVE = BASE + 18;
+ /** @hide */
+ public static final int STOP_RESOLVE_FAILED = BASE + 19;
+ /** @hide */
+ public static final int STOP_RESOLVE_SUCCEEDED = BASE + 20;
+
+
+
/**
* Create a new Nsd instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -117,10 +126,23 @@ public class NsdManager {
/**
* Indicates that the operation failed because the framework is busy and
- * unable to service the request
+ * unable to service the request.
*/
public static final int BUSY = 2;
+ /**
+ * Indicates that the operation failed because it is already active.
+ */
+ public static final int ALREADY_ACTIVE = 3;
+
+ /**
+ * Indicates that the operation failed because maximum limit on
+ * service registrations has reached.
+ */
+ public static final int MAX_REGS_REACHED = 4;
+
+
+
/** Interface for callback invocation when framework channel is connected or lost */
public interface ChannelListener {
public void onChannelConnected(Channel c);
@@ -188,6 +210,7 @@ public class NsdManager {
private DnsSdRegisterListener mDnsSdRegisterListener;
private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
private DnsSdResolveListener mDnsSdResolveListener;
+ private ActionListener mDnsSdStopResolveListener;
AsyncChannel mAsyncChannel;
ServiceHandler mHandler;
@@ -278,6 +301,16 @@ public class NsdManager {
(DnsSdServiceInfo) message.obj);
}
break;
+ case STOP_RESOLVE_FAILED:
+ if (mDnsSdStopResolveListener!= null) {
+ mDnsSdStopResolveListener.onFailure(message.arg1);
+ }
+ break;
+ case STOP_RESOLVE_SUCCEEDED:
+ if (mDnsSdStopResolveListener != null) {
+ mDnsSdStopResolveListener.onSuccess();
+ }
+ break;
default:
Log.d(TAG, "Ignored " + message);
break;
@@ -345,6 +378,14 @@ public class NsdManager {
c.mDnsSdResolveListener = b;
}
+ /**
+ * Set the listener for stopping service resolution. Can be null.
+ */
+ public void setStopResolveListener(Channel c, ActionListener b) {
+ if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ c.mDnsSdStopResolveListener = b;
+ }
+
public void registerService(Channel c, DnsSdServiceInfo serviceInfo) {
if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
if (serviceInfo == null) throw new IllegalArgumentException("Null serviceInfo");
@@ -378,6 +419,13 @@ public class NsdManager {
c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo);
}
+ public void stopServiceResolve(Channel c) {
+ if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ if (c.mDnsSdResolveListener == null) throw new
+ IllegalStateException("Resolve listener needs to be set first");
+ c.mAsyncChannel.sendMessage(STOP_RESOLVE);
+ }
+
/**
* Get a reference to NetworkService handler. This is used to establish
* an AsyncChannel communication with the service
diff --git a/core/java/android/provider/BrowserContract.java b/core/java/android/provider/BrowserContract.java
index d678205..118b5eb 100644
--- a/core/java/android/provider/BrowserContract.java
+++ b/core/java/android/provider/BrowserContract.java
@@ -30,6 +30,15 @@ import android.os.RemoteException;
import android.util.Pair;
/**
+ * <p>
+ * The contract between the browser provider and applications. Contains the definition
+ * for the supported URIS and columns.
+ * </p>
+ * <h3>Overview</h3>
+ * <p>
+ * BrowserContract defines an database of browser-related information which are bookmarks,
+ * history, images and the mapping between the image and URL.
+ * </p>
* @hide
*/
public class BrowserContract {
@@ -45,12 +54,14 @@ public class BrowserContract {
* the dirty flag is not automatically set and the "syncToNetwork" parameter
* is set to false when calling
* {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}.
+ * @hide
*/
public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
/**
* A parameter for use when querying any table that allows specifying a limit on the number
* of rows returned.
+ * @hide
*/
public static final String PARAM_LIMIT = "limit";
@@ -58,6 +69,8 @@ public class BrowserContract {
* Generic columns for use by sync adapters. The specific functions of
* these columns are private to the sync adapter. Other clients of the API
* should not attempt to either read or write these columns.
+ *
+ * @hide
*/
interface BaseSyncColumns {
/** Generic column for use by sync adapters. */
@@ -74,6 +87,7 @@ public class BrowserContract {
/**
* Convenience definitions for use in implementing chrome bookmarks sync in the Bookmarks table.
+ * @hide
*/
public static final class ChromeSyncColumns {
private ChromeSyncColumns() {}
@@ -93,6 +107,7 @@ public class BrowserContract {
/**
* Columns that appear when each row of a table belongs to a specific
* account, including sync information that an account may need.
+ * @hide
*/
interface SyncColumns extends BaseSyncColumns {
/**
@@ -144,13 +159,14 @@ public class BrowserContract {
public static final String _ID = "_id";
/**
- * The URL of the bookmark.
+ * This column is valid when the row is a URL. The history table's URL
+ * can not be updated.
* <P>Type: TEXT (URL)</P>
*/
public static final String URL = "url";
/**
- * The user visible title of the bookmark.
+ * The user visible title.
* <P>Type: TEXT</P>
*/
public static final String TITLE = "title";
@@ -159,10 +175,14 @@ public class BrowserContract {
* The time that this row was created on its originating client (msecs
* since the epoch).
* <P>Type: INTEGER</P>
+ * @hide
*/
public static final String DATE_CREATED = "created";
}
+ /**
+ * @hide
+ */
interface ImageColumns {
/**
* The favicon of the bookmark, may be NULL.
@@ -182,7 +202,6 @@ public class BrowserContract {
* The touch icon for the web page, may be NULL.
* Must decode via {@link BitmapFactory#decodeByteArray}.
* <p>Type: BLOB (image)</p>
- * @hide
*/
public static final String TOUCH_ICON = "touch_icon";
}
@@ -200,9 +219,26 @@ public class BrowserContract {
*/
public static final String VISITS = "visits";
+ /**
+ * @hide
+ */
public static final String USER_ENTERED = "user_entered";
}
+ interface ImageMappingColumns {
+ /**
+ * The ID of the image in Images. One image can map onto the multiple URLs.
+ * <P>Type: INTEGER (long)</P>
+ */
+ public static final String IMAGE_ID = "image_id";
+
+ /**
+ * The URL. The URL can map onto the different type of images.
+ * <P>Type: TEXT (URL)</P>
+ */
+ public static final String URL = "url";
+ }
+
/**
* The bookmarks table, which holds the user's browser bookmarks.
*/
@@ -218,24 +254,71 @@ public class BrowserContract {
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "bookmarks");
/**
+ * Used in {@link Bookmarks#TYPE} column and indicats the row is a bookmark.
+ */
+ public static final int BOOKMARK_TYPE_BOOKMARK = 1;
+
+ /**
+ * Used in {@link Bookmarks#TYPE} column and indicats the row is a folder.
+ */
+ public static final int BOOKMARK_TYPE_FOLDER = 2;
+
+ /**
+ * Used in {@link Bookmarks#TYPE} column and indicats the row is the bookmark bar folder.
+ */
+ public static final int BOOKMARK_TYPE_BOOKMARK_BAR_FOLDER = 3;
+
+ /**
+ * Used in {@link Bookmarks#TYPE} column and indicats the row is other folder and
+ */
+ public static final int BOOKMARK_TYPE_OTHER_FOLDER = 4;
+
+ /**
+ * Used in {@link Bookmarks#TYPE} column and indicats the row is other folder, .
+ */
+ public static final int BOOKMARK_TYPE_MOBILE_FOLDER = 5;
+
+ /**
+ * The type of the item.
+ * <P>Type: INTEGER</P>
+ * <p>Allowed values are:</p>
+ * <p>
+ * <ul>
+ * <li>{@link #BOOKMARK_TYPE_BOOKMARK}</li>
+ * <li>{@link #BOOKMARK_TYPE_FOLDER}</li>
+ * <li>{@link #BOOKMARK_TYPE_BOOKMARK_BAR_FOLDER}</li>
+ * <li>{@link #BOOKMARK_TYPE_OTHER_FOLDER}</li>
+ * <li>{@link #BOOKMARK_TYPE_MOBILE_FOLDER}</li>
+ * </ul>
+ * </p>
+ * <p> The TYPE_BOOKMARK_BAR_FOLDER, TYPE_OTHER_FOLDER and TYPE_MOBILE_FOLDER
+ * can not be updated or deleted.</p>
+ */
+ public static final String TYPE = "type";
+
+ /**
* The content:// style URI for the default folder
+ * @hide
*/
public static final Uri CONTENT_URI_DEFAULT_FOLDER =
Uri.withAppendedPath(CONTENT_URI, "folder");
/**
* Query parameter used to specify an account name
+ * @hide
*/
public static final String PARAM_ACCOUNT_NAME = "acct_name";
/**
* Query parameter used to specify an account type
+ * @hide
*/
public static final String PARAM_ACCOUNT_TYPE = "acct_type";
/**
* Builds a URI that points to a specific folder.
* @param folderId the ID of the folder to point to
+ * @hide
*/
public static final Uri buildFolderUri(long folderId) {
return ContentUris.withAppendedId(CONTENT_URI_DEFAULT_FOLDER, folderId);
@@ -255,6 +338,7 @@ public class BrowserContract {
* Query parameter to use if you want to see deleted bookmarks that are still
* around on the device and haven't been synced yet.
* @see #IS_DELETED
+ * @hide
*/
public static final String QUERY_PARAMETER_SHOW_DELETED = "show_deleted";
@@ -262,6 +346,7 @@ public class BrowserContract {
* Flag indicating if an item is a folder or bookmark. Non-zero values indicate
* a folder and zero indicates a bookmark.
* <P>Type: INTEGER (boolean)</P>
+ * @hide
*/
public static final String IS_FOLDER = "folder";
@@ -274,6 +359,7 @@ public class BrowserContract {
/**
* The source ID for an item's parent. Read-only.
* @see #PARENT
+ * @hide
*/
public static final String PARENT_SOURCE_ID = "parent_source";
@@ -281,6 +367,7 @@ public class BrowserContract {
* The position of the bookmark in relation to it's siblings that share the same
* {@link #PARENT}. May be negative.
* <P>Type: INTEGER</P>
+ * @hide
*/
public static final String POSITION = "position";
@@ -288,6 +375,7 @@ public class BrowserContract {
* The item that the bookmark should be inserted after.
* May be negative.
* <P>Type: INTEGER</P>
+ * @hide
*/
public static final String INSERT_AFTER = "insert_after";
@@ -296,6 +384,7 @@ public class BrowserContract {
* May be negative.
* <P>Type: INTEGER</P>
* @see #INSERT_AFTER
+ * @hide
*/
public static final String INSERT_AFTER_SOURCE_ID = "insert_after_source";
@@ -305,12 +394,14 @@ public class BrowserContract {
* to the URI when performing your query.
* <p>Type: INTEGER (non-zero if the item has been deleted, zero if it hasn't)
* @see #QUERY_PARAMETER_SHOW_DELETED
+ * @hide
*/
public static final String IS_DELETED = "deleted";
}
/**
* Read-only table that lists all the accounts that are used to provide bookmarks.
+ * @hide
*/
public static final class Accounts {
/**
@@ -410,6 +501,7 @@ public class BrowserContract {
* A table provided for sync adapters to use for storing private sync state data.
*
* @see SyncStateContract
+ * @hide
*/
public static final class SyncState implements SyncStateContract.Columns {
/**
@@ -459,8 +551,18 @@ public class BrowserContract {
}
/**
- * Stores images for URLs. Only support query() and update().
- * @hide
+ * <p>
+ * Stores images for URLs.
+ * </p>
+ * <p>
+ * The rows in this table can not be updated since there might have multiple URLs mapping onto
+ * the same image. If you want to update a URL's image, you need to add the new image in this
+ * table, then update the mapping onto the added image.
+ * </p>
+ * <p>
+ * Every image should be at least associated with one URL, otherwise it will be removed after a
+ * while.
+ * </p>
*/
public static final class Images implements ImageColumns {
/**
@@ -474,15 +576,93 @@ public class BrowserContract {
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "images");
/**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of images.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/images";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} of a single image.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/images";
+
+ /**
+ * Used in {@link Images#TYPE} column and indicats the row is a favicon.
+ */
+ public static final int IMAGE_TYPE_FAVICON = 1;
+
+ /**
+ * Used in {@link Images#TYPE} column and indicats the row is a precomposed touch icon.
+ */
+ public static final int IMAGE_TYPE_PRECOMPOSED_TOUCH_ICON = 2;
+
+ /**
+ * Used in {@link Images#TYPE} column and indicats the row is a touch icon.
+ */
+ public static final int IMAGE_TYPE_TOUCH_ICON = 4;
+
+ /**
+ * The type of item in the table.
+ * <P>Type: INTEGER</P>
+ * <p>Allowed values are:</p>
+ * <p>
+ * <ul>
+ * <li>{@link #IMAGE_TYPE_FAVICON}</li>
+ * <li>{@link #IMAGE_TYPE_PRECOMPOSED_TOUCH_ICON}</li>
+ * <li>{@link #IMAGE_TYPE_TOUCH_ICON}</li>
+ * </ul>
+ * </p>
+ */
+ public static final String TYPE = "type";
+
+ /**
+ * The image data.
+ * <p>Type: BLOB (image)</p>
+ */
+ public static final String DATA = "data";
+
+ /**
* The URL the images came from.
* <P>Type: TEXT (URL)</P>
+ * @hide
*/
public static final String URL = "url_key";
}
/**
+ * <p>
+ * A table that stores the mappings between the image and the URL.
+ * </p>
+ * <p>
+ * Deleting or Updating a mapping might also deletes the mapped image if there is no other URL
+ * maps onto it.
+ * </p>
+ */
+ public static final class ImageMappings implements ImageMappingColumns {
+ /**
+ * This utility class cannot be instantiated
+ */
+ private ImageMappings() {}
+
+ /**
+ * The content:// style URI for this table
+ */
+ public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "image_mappings");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of image mappings.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image_mappings";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} of a single image mapping.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/image_mappings";
+ }
+
+ /**
* A combined view of bookmarks and history. All bookmarks in all folders are included and
* no folders are included.
+ * @hide
*/
public static final class Combined implements CommonColumns, HistoryColumns, ImageColumns {
/**
@@ -505,6 +685,7 @@ public class BrowserContract {
/**
* A table that stores settings specific to the browser. Only support query and insert.
+ * @hide
*/
public static final class Settings {
/**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 0e9306b..e4729c7 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -7452,7 +7452,7 @@ public final class ContactsContract {
/**
* <p>
* API allowing applications to send usage information for each {@link Data} row to the
- * Contacts Provider.
+ * Contacts Provider. Applications can also clear all usage information.
* </p>
* <p>
* With the feedback, Contacts Provider may return more contextually appropriate results for
@@ -7497,6 +7497,12 @@ public final class ContactsContract {
* boolean successful = resolver.update(uri, new ContentValues(), null, null) > 0;
* </pre>
* </p>
+ * <p>
+ * Applications can also clear all usage information with:
+ * <pre>
+ * boolean successful = resolver.delete(DataUsageFeedback.FEEDBACK_URI, null, null) > 0;
+ * </pre>
+ * </p>
*/
public static final class DataUsageFeedback {
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 6056c75..11c169e 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -75,7 +75,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
if (spans[i] instanceof NoCopySpan) {
continue;
}
-
+
int st = sp.getSpanStart(spans[i]) - start;
int en = sp.getSpanEnd(spans[i]) - start;
int fl = sp.getSpanFlags(spans[i]);
@@ -212,7 +212,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
if (mGapLength > 2 * length())
resizeFor(length());
-
+
return ret; // == this
}
@@ -220,7 +220,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
public void clear() {
replace(0, length(), "", 0, 0);
}
-
+
// Documentation from interface
public void clearSpans() {
for (int i = mSpanCount - 1; i >= 0; i--) {
@@ -257,45 +257,50 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
return append(String.valueOf(text));
}
- private void change(int start, int end, CharSequence tb, int tbstart, int tbend) {
- checkRange("replace", start, end);
+ private void change(int start, int end, CharSequence cs, int csStart, int csEnd) {
+ // Can be negative
+ final int nbNewChars = (csEnd - csStart) - (end - start);
for (int i = mSpanCount - 1; i >= 0; i--) {
- if ((mSpanFlags[i] & SPAN_PARAGRAPH) == SPAN_PARAGRAPH) {
- int st = mSpanStarts[i];
- if (st > mGapStart)
- st -= mGapLength;
+ int spanStart = mSpanStarts[i];
+ if (spanStart > mGapStart)
+ spanStart -= mGapLength;
- int en = mSpanEnds[i];
- if (en > mGapStart)
- en -= mGapLength;
+ int spanEnd = mSpanEnds[i];
+ if (spanEnd > mGapStart)
+ spanEnd -= mGapLength;
- int ost = st;
- int oen = en;
+ if ((mSpanFlags[i] & SPAN_PARAGRAPH) == SPAN_PARAGRAPH) {
+ int ost = spanStart;
+ int oen = spanEnd;
int clen = length();
- if (st > start && st <= end) {
- for (st = end; st < clen; st++)
- if (st > end && charAt(st - 1) == '\n')
+ if (spanStart > start && spanStart <= end) {
+ for (spanStart = end; spanStart < clen; spanStart++)
+ if (spanStart > end && charAt(spanStart - 1) == '\n')
break;
}
- if (en > start && en <= end) {
- for (en = end; en < clen; en++)
- if (en > end && charAt(en - 1) == '\n')
+ if (spanEnd > start && spanEnd <= end) {
+ for (spanEnd = end; spanEnd < clen; spanEnd++)
+ if (spanEnd > end && charAt(spanEnd - 1) == '\n')
break;
}
- if (st != ost || en != oen)
- setSpan(false, mSpans[i], st, en, mSpanFlags[i]);
+ if (spanStart != ost || spanEnd != oen)
+ setSpan(false, mSpans[i], spanStart, spanEnd, mSpanFlags[i]);
}
+
+ int flags = 0;
+ if (spanStart == start) flags |= SPAN_START_AT_START;
+ else if (spanStart == end + nbNewChars) flags |= SPAN_START_AT_END;
+ if (spanEnd == start) flags |= SPAN_END_AT_START;
+ else if (spanEnd == end + nbNewChars) flags |= SPAN_END_AT_END;
+ mSpanFlags[i] |= flags;
}
moveGapTo(end);
- // Can be negative
- final int nbNewChars = (tbend - tbstart) - (end - start);
-
if (nbNewChars >= mGapLength) {
resizeFor(mText.length + nbNewChars - mGapLength);
}
@@ -306,7 +311,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
if (mGapLength < 1)
new Exception("mGapLength < 1").printStackTrace();
- TextUtils.getChars(tb, tbstart, tbend, mText, start);
+ TextUtils.getChars(cs, csStart, csEnd, mText, start);
if (end > start) {
// no need for span fixup on pure insertion
@@ -340,21 +345,23 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
}
}
- if (tb instanceof Spanned) {
- Spanned sp = (Spanned) tb;
- Object[] spans = sp.getSpans(tbstart, tbend, Object.class);
+ mSpanCountBeforeAdd = mSpanCount;
+
+ if (cs instanceof Spanned) {
+ Spanned sp = (Spanned) cs;
+ Object[] spans = sp.getSpans(csStart, csEnd, Object.class);
for (int i = 0; i < spans.length; i++) {
int st = sp.getSpanStart(spans[i]);
int en = sp.getSpanEnd(spans[i]);
- if (st < tbstart) st = tbstart;
- if (en > tbend) en = tbend;
+ if (st < csStart) st = csStart;
+ if (en > csEnd) en = csEnd;
// Add span only if this object is not yet used as a span in this string
- if (getSpanStart(spans[i]) < 0) {
- setSpan(false, spans[i], st - tbstart + start, en - tbstart + start,
- sp.getSpanFlags(spans[i]));
+ if (getSpanStart(spans[i]) < 0 && !(spans[i] instanceof SpanWatcher)) {
+ setSpan(false, spans[i], st - csStart + start, en - csStart + start,
+ sp.getSpanFlags(spans[i]));
}
}
}
@@ -390,6 +397,8 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
// Documentation from interface
public SpannableStringBuilder replace(final int start, final int end,
CharSequence tb, int tbstart, int tbend) {
+ checkRange("replace", start, end);
+
int filtercount = mFilters.length;
for (int i = 0; i < filtercount; i++) {
CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
@@ -404,10 +413,6 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
final int origLen = end - start;
final int newLen = tbend - tbstart;
- if (origLen == 0 && newLen == 0) {
- return this;
- }
-
TextWatcher[] textWatchers = getSpans(start, start + origLen, TextWatcher.class);
sendBeforeTextChanged(textWatchers, start, origLen, newLen);
@@ -415,43 +420,101 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
// a text replacement. If replaced or replacement text length is zero, this
// is already taken care of.
boolean adjustSelection = origLen != 0 && newLen != 0;
- int selstart = 0;
- int selend = 0;
+ int selectionStart = 0;
+ int selectionEnd = 0;
if (adjustSelection) {
- selstart = Selection.getSelectionStart(this);
- selend = Selection.getSelectionEnd(this);
+ selectionStart = Selection.getSelectionStart(this);
+ selectionEnd = Selection.getSelectionEnd(this);
}
- checkRange("replace", start, end);
-
change(start, end, tb, tbstart, tbend);
if (adjustSelection) {
- if (selstart > start && selstart < end) {
- long off = selstart - start;
-
- off = off * newLen / origLen;
- selstart = (int) off + start;
+ if (selectionStart > start && selectionStart < end) {
+ final int offset = (selectionStart - start) * newLen / origLen;
+ selectionStart = start + offset;
- setSpan(false, Selection.SELECTION_START, selstart, selstart,
+ setSpan(false, Selection.SELECTION_START, selectionStart, selectionStart,
Spanned.SPAN_POINT_POINT);
}
- if (selend > start && selend < end) {
- long off = selend - start;
+ if (selectionEnd > start && selectionEnd < end) {
+ final int offset = (selectionEnd - start) * newLen / origLen;
+ selectionEnd = start + offset;
- off = off * newLen / origLen;
- selend = (int) off + start;
-
- setSpan(false, Selection.SELECTION_END, selend, selend, Spanned.SPAN_POINT_POINT);
+ setSpan(false, Selection.SELECTION_END, selectionEnd, selectionEnd,
+ Spanned.SPAN_POINT_POINT);
}
}
sendTextChanged(textWatchers, start, origLen, newLen);
sendAfterTextChanged(textWatchers);
+ // Span watchers need to be called after text watchers, which may update the layout
+ sendToSpanWatchers(start, end, newLen - origLen);
+
return this;
}
+ private void sendToSpanWatchers(int replaceStart, int replaceEnd, int nbNewChars) {
+ for (int i = 0; i < mSpanCountBeforeAdd; i++) {
+ int spanStart = mSpanStarts[i];
+ int spanEnd = mSpanEnds[i];
+ if (spanStart > mGapStart) spanStart -= mGapLength;
+ if (spanEnd > mGapStart) spanEnd -= mGapLength;
+ int spanFlags = mSpanFlags[i];
+
+ int newReplaceEnd = replaceEnd + nbNewChars;
+ boolean spanChanged = false;
+ int previousSpanStart = spanStart;
+ if (spanStart > newReplaceEnd) {
+ if (nbNewChars != 0) {
+ previousSpanStart -= nbNewChars;
+ spanChanged = true;
+ }
+ } else if (spanStart >= replaceStart) {
+ // No change if span start was already at replace interval boundaries before replace
+ if ((spanStart != replaceStart ||
+ ((spanFlags & SPAN_START_AT_START) != SPAN_START_AT_START)) &&
+ (spanStart != newReplaceEnd ||
+ ((spanFlags & SPAN_START_AT_END) != SPAN_START_AT_END))) {
+ // TODO previousSpanStart is incorrect, but we would need to save all the
+ // previous spans' positions before replace to provide it
+ spanChanged = true;
+ }
+ }
+ int previousSpanEnd = spanEnd;
+ if (spanEnd > newReplaceEnd) {
+ if (nbNewChars != 0) {
+ previousSpanEnd -= nbNewChars;
+ spanChanged = true;
+ }
+ } else if (spanEnd >= replaceStart) {
+ // No change if span start was already at replace interval boundaries before replace
+ if ((spanEnd != replaceStart ||
+ ((spanFlags & SPAN_END_AT_START) != SPAN_END_AT_START)) &&
+ (spanEnd != newReplaceEnd ||
+ ((spanFlags & SPAN_END_AT_END) != SPAN_END_AT_END))) {
+ // TODO same as above for previousSpanEnd
+ spanChanged = true;
+ }
+ }
+
+ if (spanChanged) {
+ sendSpanChanged(mSpans[i], previousSpanStart, previousSpanEnd, spanStart, spanEnd);
+ }
+ mSpanFlags[i] &= ~SPAN_START_END_MASK;
+ }
+
+ // The spans starting at mIntermediateSpanCount were added from the replacement text
+ for (int i = mSpanCountBeforeAdd; i < mSpanCount; i++) {
+ int spanStart = mSpanStarts[i];
+ int spanEnd = mSpanEnds[i];
+ if (spanStart > mGapStart) spanStart -= mGapLength;
+ if (spanEnd > mGapStart) spanEnd -= mGapLength;
+ sendSpanAdded(mSpans[i], spanStart, spanEnd);
+ }
+ }
+
/**
* Mark the specified range of text with the specified object.
* The flags determine how the span will behave when text is
@@ -788,13 +851,12 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
if (end <= mGapStart) {
System.arraycopy(mText, start, dest, destoff, end - start);
} else if (start >= mGapStart) {
- System.arraycopy(mText, start + mGapLength,
- dest, destoff, end - start);
+ System.arraycopy(mText, start + mGapLength, dest, destoff, end - start);
} else {
System.arraycopy(mText, start, dest, destoff, mGapStart - start);
System.arraycopy(mText, mGapStart + mGapLength,
- dest, destoff + (mGapStart - start),
- end - mGapStart);
+ dest, destoff + (mGapStart - start),
+ end - mGapStart);
}
}
@@ -863,12 +925,14 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
}
}
- private void sendSpanChanged(Object what, int s, int e, int st, int en) {
- SpanWatcher[] recip = getSpans(Math.min(s, st), Math.max(e, en), SpanWatcher.class);
- int n = recip.length;
-
+ private void sendSpanChanged(Object what, int oldStart, int oldEnd, int start, int end) {
+ // The bounds of a possible SpanWatcher are guaranteed to be set before this method is
+ // called, so that the order of the span does not affect this broadcast.
+ SpanWatcher[] spanWatchers = getSpans(Math.min(oldStart, start),
+ Math.min(Math.max(oldEnd, end), length()), SpanWatcher.class);
+ int n = spanWatchers.length;
for (int i = 0; i < n; i++) {
- recip[i].onSpanChanged(this, what, s, e, st, en);
+ spanWatchers[i].onSpanChanged(this, what, oldStart, oldEnd, start, end);
}
}
@@ -879,26 +943,23 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
private void checkRange(final String operation, int start, int end) {
if (end < start) {
throw new IndexOutOfBoundsException(operation + " " +
- region(start, end) +
- " has end before start");
+ region(start, end) + " has end before start");
}
int len = length();
if (start > len || end > len) {
throw new IndexOutOfBoundsException(operation + " " +
- region(start, end) +
- " ends beyond length " + len);
+ region(start, end) + " ends beyond length " + len);
}
if (start < 0 || end < 0) {
throw new IndexOutOfBoundsException(operation + " " +
- region(start, end) +
- " starts before 0");
+ region(start, end) + " starts before 0");
}
}
-/*
+ /*
private boolean isprint(char c) { // XXX
if (c >= ' ' && c <= '~')
return true;
@@ -977,7 +1038,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
System.out.print("\n");
}
-*/
+ */
/**
* Don't call this yourself -- exists for Canvas to use internally.
@@ -1023,7 +1084,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
}
}
- /**
+ /**
* Don't call this yourself -- exists for Paint to use internally.
* {@hide}
*/
@@ -1059,8 +1120,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
if (end <= mGapStart) {
ret = p.getTextWidths(mText, start, end - start, widths);
} else if (start >= mGapStart) {
- ret = p.getTextWidths(mText, start + mGapLength, end - start,
- widths);
+ ret = p.getTextWidths(mText, start + mGapLength, end - start, widths);
} else {
char[] buf = TextUtils.obtain(end - start);
@@ -1205,6 +1265,7 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
private int[] mSpanEnds;
private int[] mSpanFlags;
private int mSpanCount;
+ private int mSpanCountBeforeAdd;
// TODO These value are tightly related to the public SPAN_MARK/POINT values in {@link Spanned}
private static final int MARK = 1;
@@ -1214,4 +1275,11 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
private static final int START_MASK = 0xF0;
private static final int END_MASK = 0x0F;
private static final int START_SHIFT = 4;
+
+ // These bits are not (currently) used by SPANNED flags
+ private static final int SPAN_START_AT_START = 0x1000;
+ private static final int SPAN_START_AT_END = 0x2000;
+ private static final int SPAN_END_AT_START = 0x4000;
+ private static final int SPAN_END_AT_END = 0x8000;
+ private static final int SPAN_START_END_MASK = 0xF000;
}
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index ba62e65..32029ba 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -187,7 +187,9 @@ public class TextureView extends View {
public void setOpaque(boolean opaque) {
if (opaque != mOpaque) {
mOpaque = opaque;
- updateLayer();
+ if (mLayer != null) {
+ updateLayer();
+ }
}
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 7ccc7fe..851fd22 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -828,6 +828,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
// the screen all-the-time. Good for profiling our drawing code
static private final boolean AUTO_REDRAW_HACK = false;
+
+ // The rate at which edit text is scrolled in content pixels per millisecond
+ static private final float TEXT_SCROLL_RATE = 0.01f;
+
+ // The presumed scroll rate for the first scroll of edit text
+ static private final long TEXT_SCROLL_FIRST_SCROLL_MS = 16;
+
// true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
private boolean mAutoRedraw;
@@ -853,6 +860,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
boolean mIsEditingText = false;
ArrayList<Message> mBatchedTextChanges = new ArrayList<Message>();
boolean mIsBatchingTextChanges = false;
+ private long mLastEditScroll = 0;
private static class OnTrimMemoryListener implements ComponentCallbacks2 {
private static OnTrimMemoryListener sInstance = null;
@@ -1037,9 +1045,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// pages with the space bar, in pixels.
private static final int PAGE_SCROLL_OVERLAP = 24;
- // Time between successive calls to text scroll fling animation
- private static final int TEXT_SCROLL_ANIMATION_DELAY_MS = 16;
-
/**
* These prevent calling requestLayout if either dimension is fixed. This
* depends on the layout parameters and the measure specs.
@@ -1207,7 +1212,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
static final int RELOCATE_AUTO_COMPLETE_POPUP = 146;
static final int FOCUS_NODE_CHANGED = 147;
static final int AUTOFILL_FORM = 148;
- static final int ANIMATE_TEXT_SCROLL = 149;
+ static final int SCROLL_EDIT_TEXT = 149;
static final int EDIT_TEXT_SIZE_CHANGED = 150;
static final int SHOW_CARET_HANDLE = 151;
static final int UPDATE_CONTENT_BOUNDS = 152;
@@ -6091,6 +6096,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mSelectDraggingTextQuad.containsPoint(handleX, handleY);
boolean inEditBounds = mEditTextContentBounds
.contains(handleX, handleY);
+ if (mIsEditingText && !inEditBounds) {
+ beginScrollEdit();
+ } else {
+ endScrollEdit();
+ }
if (inCursorText || (mIsEditingText && !inEditBounds)) {
snapDraggingCursor();
}
@@ -6240,6 +6250,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
break;
}
case MotionEvent.ACTION_UP: {
+ endScrollEdit();
if (!mConfirmMove && mIsEditingText && mSelectionStarted &&
mIsCaretSelection) {
showPasteWindow();
@@ -6335,6 +6346,86 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
}
+ /**
+ * Returns the text scroll speed in content pixels per millisecond based on
+ * the touch location.
+ * @param coordinate The x or y touch coordinate in content space
+ * @param min The minimum coordinate (x or y) of the edit content bounds
+ * @param max The maximum coordinate (x or y) of the edit content bounds
+ */
+ private static float getTextScrollSpeed(int coordinate, int min, int max) {
+ if (coordinate < min) {
+ return (coordinate - min) * TEXT_SCROLL_RATE;
+ } else if (coordinate >= max) {
+ return (coordinate - max + 1) * TEXT_SCROLL_RATE;
+ } else {
+ return 0.0f;
+ }
+ }
+
+ private void beginScrollEdit() {
+ if (mLastEditScroll == 0) {
+ mLastEditScroll = SystemClock.uptimeMillis() -
+ TEXT_SCROLL_FIRST_SCROLL_MS;
+ scrollEditWithCursor();
+ }
+ }
+
+ private void endScrollEdit() {
+ mLastEditScroll = 0;
+ }
+
+ private static int getTextScrollDelta(float speed, long deltaT) {
+ float distance = speed * deltaT;
+ int intDistance = (int)Math.floor(distance);
+ float probability = distance - intDistance;
+ if (Math.random() < probability) {
+ intDistance++;
+ }
+ return intDistance;
+ }
+ /**
+ * Scrolls edit text a distance based on the last touch point,
+ * the last scroll time, and the edit text content bounds.
+ */
+ private void scrollEditWithCursor() {
+ if (mLastEditScroll != 0) {
+ int x = viewToContentX(mLastTouchX + getScrollX() + mSelectDraggingOffset.x);
+ float scrollSpeedX = getTextScrollSpeed(x, mEditTextContentBounds.left,
+ mEditTextContentBounds.right);
+ int y = viewToContentY(mLastTouchY + getScrollY() + mSelectDraggingOffset.y);
+ float scrollSpeedY = getTextScrollSpeed(y, mEditTextContentBounds.top,
+ mEditTextContentBounds.bottom);
+ if (scrollSpeedX == 0.0f && scrollSpeedY == 0.0f) {
+ endScrollEdit();
+ } else {
+ long currentTime = SystemClock.uptimeMillis();
+ long timeSinceLastUpdate = currentTime - mLastEditScroll;
+ int deltaX = getTextScrollDelta(scrollSpeedX, timeSinceLastUpdate);
+ int deltaY = getTextScrollDelta(scrollSpeedY, timeSinceLastUpdate);
+ mLastEditScroll = currentTime;
+ if (deltaX == 0 && deltaY == 0) {
+ // By probability no text scroll this time. Try again later.
+ mPrivateHandler.sendEmptyMessageDelayed(SCROLL_EDIT_TEXT,
+ TEXT_SCROLL_FIRST_SCROLL_MS);
+ } else {
+ int scrollX = getTextScrollX() + deltaX;
+ scrollX = Math.min(getMaxTextScrollX(), scrollX);
+ scrollX = Math.max(0, scrollX);
+ int scrollY = getTextScrollY() + deltaY;
+ scrollY = Math.min(getMaxTextScrollY(), scrollY);
+ scrollY = Math.max(0, scrollY);
+ scrollEditText(scrollX, scrollY);
+ int cursorX = mSelectDraggingCursor.x;
+ int cursorY = mSelectDraggingCursor.y;
+ mSelectDraggingCursor.set(x - deltaX, y - deltaY);
+ updateWebkitSelection();
+ mSelectDraggingCursor.set(cursorX, cursorY);
+ }
+ }
+ }
+ }
+
private void startTouch(float x, float y, long eventTime) {
// Remember where the motion event started
mStartTouchX = mLastTouchX = Math.round(x);
@@ -7673,10 +7764,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
msg.arg1, /* unused */0);
break;
- case ANIMATE_TEXT_SCROLL:
- computeEditTextScroll();
- break;
-
case EDIT_TEXT_SIZE_CHANGED:
if (msg.arg1 == mFieldPointer) {
mEditTextContent.set((Rect)msg.obj);
@@ -7695,6 +7782,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mEditTextContentBounds.set((Rect) msg.obj);
break;
+ case SCROLL_EDIT_TEXT:
+ scrollEditWithCursor();
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -8008,6 +8099,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (isPictureAfterFirstLayout) {
mViewManager.postReadyToDrawAll();
}
+ scrollEditWithCursor();
}
/**
@@ -8050,13 +8142,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
invalidate();
}
- private void computeEditTextScroll() {
- if (mEditTextScroller.computeScrollOffset()) {
- scrollEditText(mEditTextScroller.getCurrX(),
- mEditTextScroller.getCurrY());
- }
- }
-
private void scrollEditText(int scrollX, int scrollY) {
// Scrollable edit text. Scroll it.
float maxScrollX = getMaxTextScrollX();
@@ -8064,8 +8149,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mEditTextContent.offsetTo(-scrollX, -scrollY);
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SCROLL_TEXT_INPUT, 0,
scrollY, (Float)scrollPercentX);
- mPrivateHandler.sendEmptyMessageDelayed(ANIMATE_TEXT_SCROLL,
- TEXT_SCROLL_ANIMATION_DELAY_MS);
}
private void beginTextBatch() {
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index d897a39..b2321d9 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -579,7 +579,7 @@ public class NumberPicker extends LinearLayout {
throw new IllegalArgumentException("minWidth > maxWidth");
}
- mComputeMaxWidth = (mMaxWidth == Integer.MAX_VALUE);
+ mComputeMaxWidth = (mMaxWidth == SIZE_UNSPECIFIED);
attributesArray.recycle();
@@ -771,6 +771,8 @@ public class NumberPicker extends LinearLayout {
mLastDownEventTime = event.getEventTime();
mIngonreMoveEvents = false;
mShowSoftInputOnTap = false;
+ // Make sure we wupport flinging inside scrollables.
+ getParent().requestDisallowInterceptTouchEvent(true);
if (!mFlingScroller.isFinished()) {
mFlingScroller.forceFinished(true);
mAdjustScroller.forceFinished(true);
@@ -1096,12 +1098,7 @@ public class NumberPicker extends LinearLayout {
* @see #setMaxValue(int)
*/
public void setValue(int value) {
- if (mValue == value) {
- return;
- }
setValueInternal(value, false);
- initializeSelectorWheelIndices();
- invalidate();
}
/**
@@ -1498,6 +1495,8 @@ public class NumberPicker extends LinearLayout {
if (notifyChange) {
notifyChange(previous, current);
}
+ initializeSelectorWheelIndices();
+ invalidate();
}
/**
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index a897cc3..0786909 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -806,5 +806,16 @@ public class Switch extends CompoundButton {
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(Switch.class.getName());
+ CharSequence switchText = isChecked() ? mTextOn : mTextOff;
+ if (!TextUtils.isEmpty(switchText)) {
+ CharSequence oldText = info.getText();
+ if (TextUtils.isEmpty(oldText)) {
+ info.setText(switchText);
+ } else {
+ StringBuilder newText = new StringBuilder();
+ newText.append(oldText).append(' ').append(switchText);
+ info.setText(newText);
+ }
+ }
}
}