Merge change 5316

* changes:
  add Gservices setting for data messaging app token url.
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 4d471f7f..06148fb 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -79,6 +79,7 @@
         int httpStatusCode;
         long contentLength;
         long expires;
+        String expiresString;
         String localPath;
         String lastModified;
         String etag;
@@ -107,6 +108,10 @@
             return expires;
         }
 
+        public String getExpiresString() {
+            return expiresString;
+        }
+
         public String getLastModified() {
             return lastModified;
         }
@@ -603,17 +608,18 @@
         if (location != null) ret.location = location;
 
         ret.expires = -1;
-        String expires = headers.getExpires();
-        if (expires != null) {
+        ret.expiresString = headers.getExpires();
+        if (ret.expiresString != null) {
             try {
-                ret.expires = HttpDateTime.parse(expires);
+                ret.expires = HttpDateTime.parse(ret.expiresString);
             } catch (IllegalArgumentException ex) {
                 // Take care of the special "-1" and "0" cases
-                if ("-1".equals(expires) || "0".equals(expires)) {
+                if ("-1".equals(ret.expiresString)
+                        || "0".equals(ret.expiresString)) {
                     // make it expired, but can be used for history navigation
                     ret.expires = 0;
                 } else {
-                    Log.e(LOGTAG, "illegal expires: " + expires);
+                    Log.e(LOGTAG, "illegal expires: " + ret.expiresString);
                 }
             }
         }
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 08854f7..a87a5c2 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -949,7 +949,7 @@
         final int nativeResponse = nativeCreateResponse(
                 mUrl, statusCode, mStatusText,
                 mMimeType, mContentLength, mEncoding,
-                mCacheResult == null ? 0 : mCacheResult.expires / 1000);
+                mCacheResult == null ? null : mCacheResult.expiresString);
         if (mHeaders != null) {
             mHeaders.getHeaders(new Headers.HeaderCallback() {
                     public void header(String name, String value) {
@@ -1460,12 +1460,12 @@
      * @param expectedLength An estimate of the content length or the length
      *                       given by the server.
      * @param encoding HTTP encoding.
-     * @param expireTime HTTP expires converted to seconds since the epoch.
+     * @param expireTime HTTP expires.
      * @return The native response pointer.
      */
     private native int nativeCreateResponse(String url, int statusCode,
             String statusText, String mimeType, long expectedLength,
-            String encoding, long expireTime);
+            String encoding, String expireTime);
 
     /**
      * Add a response header to the native object.
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 1004e30..e6d89e3 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -48,7 +48,8 @@
     // 6 -> 7 Change cache localPath from int to String
     // 7 -> 8 Move cache to its own db
     // 8 -> 9 Store both scheme and host when storing passwords
-    private static final int CACHE_DATABASE_VERSION = 1;
+    private static final int CACHE_DATABASE_VERSION = 2;
+    // 1 -> 2 Add expires String
 
     private static WebViewDatabase mInstance = null;
 
@@ -107,6 +108,8 @@
 
     private static final String CACHE_EXPIRES_COL = "expires";
 
+    private static final String CACHE_EXPIRES_STRING_COL = "expiresstring";
+
     private static final String CACHE_MIMETYPE_COL = "mimetype";
 
     private static final String CACHE_ENCODING_COL = "encoding";
@@ -150,6 +153,7 @@
     private static int mCacheLastModifyColIndex;
     private static int mCacheETagColIndex;
     private static int mCacheExpiresColIndex;
+    private static int mCacheExpiresStringColIndex;
     private static int mCacheMimeTypeColIndex;
     private static int mCacheEncodingColIndex;
     private static int mCacheHttpStatusColIndex;
@@ -220,6 +224,8 @@
                         .getColumnIndex(CACHE_ETAG_COL);
                 mCacheExpiresColIndex = mCacheInserter
                         .getColumnIndex(CACHE_EXPIRES_COL);
+                mCacheExpiresStringColIndex = mCacheInserter
+                        .getColumnIndex(CACHE_EXPIRES_STRING_COL);
                 mCacheMimeTypeColIndex = mCacheInserter
                         .getColumnIndex(CACHE_MIMETYPE_COL);
                 mCacheEncodingColIndex = mCacheInserter
@@ -320,6 +326,7 @@
                     + " TEXT, " + CACHE_FILE_PATH_COL + " TEXT, "
                     + CACHE_LAST_MODIFY_COL + " TEXT, " + CACHE_ETAG_COL
                     + " TEXT, " + CACHE_EXPIRES_COL + " INTEGER, "
+                    + CACHE_EXPIRES_STRING_COL + " TEXT, "
                     + CACHE_MIMETYPE_COL + " TEXT, " + CACHE_ENCODING_COL
                     + " TEXT," + CACHE_HTTP_STATUS_COL + " INTEGER, "
                     + CACHE_LOCATION_COL + " TEXT, " + CACHE_CONTENTLENGTH_COL
@@ -537,7 +544,7 @@
         }
 
         Cursor cursor = mCacheDatabase.rawQuery("SELECT filepath, lastmodify, etag, expires, "
-                    + "mimetype, encoding, httpstatus, location, contentlength "
+                    + "expiresstring, mimetype, encoding, httpstatus, location, contentlength "
                     + "FROM cache WHERE url = ?",
                 new String[] { url });
 
@@ -548,11 +555,12 @@
                 ret.lastModified = cursor.getString(1);
                 ret.etag = cursor.getString(2);
                 ret.expires = cursor.getLong(3);
-                ret.mimeType = cursor.getString(4);
-                ret.encoding = cursor.getString(5);
-                ret.httpStatusCode = cursor.getInt(6);
-                ret.location = cursor.getString(7);
-                ret.contentLength = cursor.getLong(8);
+                ret.expiresString = cursor.getString(4);
+                ret.mimeType = cursor.getString(5);
+                ret.encoding = cursor.getString(6);
+                ret.httpStatusCode = cursor.getInt(7);
+                ret.location = cursor.getString(8);
+                ret.contentLength = cursor.getLong(9);
                 return ret;
             }
         } finally {
@@ -591,6 +599,7 @@
         mCacheInserter.bind(mCacheLastModifyColIndex, c.lastModified);
         mCacheInserter.bind(mCacheETagColIndex, c.etag);
         mCacheInserter.bind(mCacheExpiresColIndex, c.expires);
+        mCacheInserter.bind(mCacheExpiresStringColIndex, c.expiresString);
         mCacheInserter.bind(mCacheMimeTypeColIndex, c.mimeType);
         mCacheInserter.bind(mCacheEncodingColIndex, c.encoding);
         mCacheInserter.bind(mCacheHttpStatusColIndex, c.httpStatusCode);
diff --git a/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java b/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java
index 74d27ed..b3d7f69 100644
--- a/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java
+++ b/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java
@@ -38,7 +38,6 @@
 import java.io.OutputStream;
 import java.io.IOException;
 import java.lang.StringBuilder;
-import java.util.Date;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -57,7 +56,6 @@
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
 import org.apache.http.conn.ssl.StrictHostnameVerifier;
-import org.apache.http.impl.cookie.DateUtils;
 import org.apache.http.util.CharArrayBuffer;
 
 import java.util.concurrent.locks.Condition;
@@ -863,12 +861,9 @@
         mResponseHeaders = new HashMap<String, String[]>();
         String contentLength = Long.toString(cacheResult.getContentLength());
         setResponseHeader(KEY_CONTENT_LENGTH, contentLength);
-        long expires = cacheResult.getExpires();
-        if (expires >= 0) {
-            // "Expires" header is valid and finite. Milliseconds since 1970
-            // epoch, formatted as RFC-1123.
-            String expiresString = DateUtils.formatDate(new Date(expires));
-            setResponseHeader(KEY_EXPIRES, expiresString);
+        String expires = cacheResult.getExpiresString();
+        if (expires != null) {
+            setResponseHeader(KEY_EXPIRES, expires);
         }
         String lastModified = cacheResult.getLastModified();
         if (lastModified != null) {
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 6fa3141..6e6e121 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -424,6 +424,11 @@
         return sr;
     }
 
+    private void broadcastTtsQueueProcessingCompleted(){
+        Intent i = new Intent(Intent.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
+        sendBroadcast(i);
+    }
+
     private void dispatchSpeechCompletedCallbacks(String mark) {
         Log.i("TTS callback", "dispatch started");
         // Broadcast to all clients the new value.
@@ -449,11 +454,7 @@
             }
             if (mSpeechQueue.size() < 1) {
                 mIsSpeaking = false;
-                // Dispatch a completion here as this is the
-                // only place where speech completes normally.
-                // Nothing left to say in the queue is a special case
-                // that is always a "mark" - associated text is null.
-                dispatchSpeechCompletedCallbacks("");
+                broadcastTtsQueueProcessingCompleted();
                 return;
             }