Merge "Use "play" icon for search dialog button in Browser"
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 90e8c14..179b807 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1632,12 +1632,20 @@
 
     /**
      * Broadcast Action:  External media is unmounted because it is being shared via USB mass storage.
-     * The path to the mount point for the removed media is contained in the Intent.mData field.
+     * The path to the mount point for the shared media is contained in the Intent.mData field.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED";
 
     /**
+     * Broadcast Action:  External media is no longer being shared via USB mass storage.
+     * The path to the mount point for the previously shared media is contained in the Intent.mData field.
+     *
+     * @hide
+     */
+    public static final String ACTION_MEDIA_UNSHARED = "android.intent.action.MEDIA_UNSHARED";
+
+    /**
      * Broadcast Action:  External media was removed from SD card slot, but mount point was not unmounted.
      * The path to the mount point for the removed media is contained in the Intent.mData field.
      */
diff --git a/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java b/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java
new file mode 100644
index 0000000..8ac4c0f
--- /dev/null
+++ b/core/java/android/database/sqlite/DatabaseObjectNotClosedException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that garbage-collector is finalizing a database object
+ * that is not explicitly closed
+ * @hide
+ */
+public class DatabaseObjectNotClosedException extends RuntimeException
+{
+    private static final String s = "Application did not close the cursor or database object " +
+            "that was opened here";
+
+    public DatabaseObjectNotClosedException()
+    {
+        super(s);
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
index 486ad20..4ccf6b0 100644
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java
@@ -56,7 +56,7 @@
     /* package */ SQLiteCompiledSql(SQLiteDatabase db, String sql) {
         mDatabase = db;
         mSqlStmt = sql;
-        mStackTrace = new Exception().fillInStackTrace();
+        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         this.nHandle = db.mNativeHandle;
         compile(sql, true);
     }
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 96ed297..3f0fcb1 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -207,7 +207,7 @@
             String editTable, SQLiteQuery query) {
         // The AbstractCursor constructor needs to do some setup.
         super();
-        mStackTrace = new Exception().fillInStackTrace();
+        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         mDatabase = db;
         mDriver = driver;
         mEditTable = editTable;
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index d8ccf85..9fa9368 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1749,7 +1749,7 @@
         mFlags = flags;
         mPath = path;
         mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1);
-        mStackTrace = new Exception().fillInStackTrace();
+        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         mFactory = factory;
         dbopen(mPath, mFlags);
         if (SQLiteDebug.DEBUG_SQL_CACHE) {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index b28cf43..f363828 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -274,9 +274,11 @@
 
     private void onDeviceRemoved(String deviceObjectPath) {
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
-        if (address != null)
+        if (address != null) {
             mBluetoothService.getBondState().setBondState(address.toUpperCase(),
                     BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED);
+            mBluetoothService.setRemoteDeviceProperty(address, "UUIDs", null);
+        }
     }
 
     /*package*/ void onPropertyChanged(String[] propValues) {
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index db19bca..39edcad 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -822,8 +822,9 @@
                 break;
             case 1: // TEXT_AREA
                 single = false;
-                inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
+                inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
                         | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
+                        | EditorInfo.TYPE_CLASS_TEXT
                         | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
                 imeOptions |= EditorInfo.IME_ACTION_NONE;
                 break;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 72791fb..0739735 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2480,20 +2480,30 @@
      */
     public int findAll(String find) {
         if (0 == mNativeClass) return 0; // client isn't initialized
-        if (mFindIsUp == false) {
-            recordNewContentSize(mContentWidth, mContentHeight + mFindHeight,
-                    false);
-            mFindIsUp = true;
-        }
-        int result = nativeFindAll(find.toLowerCase(), find.toUpperCase());
+        int result = find != null ? nativeFindAll(find.toLowerCase(),
+                find.toUpperCase()) : 0;
         invalidate();
         mLastFind = find;
         return result;
     }
 
+    /**
+     * @hide
+     */
+    public void setFindIsUp(boolean isUp) {
+        mFindIsUp = isUp;
+        if (isUp) {
+            recordNewContentSize(mContentWidth, mContentHeight + mFindHeight,
+                    false);
+        }
+        if (0 == mNativeClass) return; // client isn't initialized
+        nativeSetFindIsUp(isUp);
+    }
+
     // Used to know whether the find dialog is open.  Affects whether
     // or not we draw the highlights for matches.
     private boolean mFindIsUp;
+
     private int mFindHeight;
     // Keep track of the last string sent, so we can search again after an
     // orientation change or the dismissal of the soft keyboard.
@@ -2553,14 +2563,21 @@
      * Clear the highlighting surrounding text matches created by findAll.
      */
     public void clearMatches() {
+        mLastFind = "";
         if (mNativeClass == 0)
             return;
-        if (mFindIsUp) {
-            recordNewContentSize(mContentWidth, mContentHeight - mFindHeight,
-                    false);
-            mFindIsUp = false;
-        }
-        nativeSetFindIsUp();
+        nativeSetFindIsEmpty();
+        invalidate();
+    }
+
+    /**
+     * @hide
+     */
+    public void notifyFindDialogDismissed() {
+        clearMatches();
+        setFindIsUp(false);
+        recordNewContentSize(mContentWidth, mContentHeight - mFindHeight,
+                false);
         // Now that the dialog has been removed, ensure that we scroll to a
         // location that is not beyond the end of the page.
         pinScrollTo(mScrollX, mScrollY, false, 0);
@@ -4477,12 +4494,12 @@
             y = getViewHeightWithTitle() - 1;
         }
 
-        // pass the touch events from UI thread to WebCore thread
-        if (mForwardTouchEvents
-                && (action != MotionEvent.ACTION_MOVE || eventTime
-                        - mLastSentTouchTime > mCurrentTouchInterval)
-                && (action == MotionEvent.ACTION_DOWN
-                        || mPreventDrag != PREVENT_DRAG_CANCEL)) {
+        // pass the touch events, except ACTION_MOVE which will be handled
+        // later, from UI thread to WebCore thread
+        if (mFullScreenHolder != null || (mForwardTouchEvents
+                && action != MotionEvent.ACTION_MOVE
+                && (action == MotionEvent.ACTION_DOWN || mPreventDrag
+                        != PREVENT_DRAG_CANCEL))) {
             WebViewCore.TouchEventData ted = new WebViewCore.TouchEventData();
             ted.mAction = action;
             ted.mX = viewToContentX((int) x + mScrollX);
@@ -4573,6 +4590,21 @@
                     if ((deltaX * deltaX + deltaY * deltaY) < mTouchSlopSquare) {
                         break;
                     }
+
+                    // pass the first ACTION_MOVE from UI thread to WebCore
+                    // thread after the distance is confirmed that it is a drag
+                    if (mFullScreenHolder == null && mForwardTouchEvents
+                            && mPreventDrag != PREVENT_DRAG_CANCEL) {
+                        WebViewCore.TouchEventData ted = new WebViewCore.TouchEventData();
+                        ted.mAction = action;
+                        ted.mX = viewToContentX((int) x + mScrollX);
+                        ted.mY = viewToContentY((int) y + mScrollY);
+                        ted.mEventTime = eventTime;
+                        ted.mMetaState = ev.getMetaState();
+                        mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
+                        mLastSentTouchTime = eventTime;
+                    }
+
                     if (mPreventDrag == PREVENT_DRAG_MAYBE_YES) {
                         // track mLastTouchTime as we may need to do fling at
                         // ACTION_UP
@@ -4629,6 +4661,20 @@
                                     Toast.LENGTH_LONG).show();
                         }
                     }
+                } else {
+                    // pass the touch events from UI thread to WebCore thread
+                    if (mFullScreenHolder == null && mForwardTouchEvents
+                            && eventTime - mLastSentTouchTime > mCurrentTouchInterval
+                            && mPreventDrag != PREVENT_DRAG_CANCEL) {
+                        WebViewCore.TouchEventData ted = new WebViewCore.TouchEventData();
+                        ted.mAction = action;
+                        ted.mX = viewToContentX((int) x + mScrollX);
+                        ted.mY = viewToContentY((int) y + mScrollY);
+                        ted.mEventTime = eventTime;
+                        ted.mMetaState = ev.getMetaState();
+                        mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
+                        mLastSentTouchTime = eventTime;
+                    }
                 }
 
                 // do pan
@@ -6863,7 +6909,8 @@
     private native void     nativeRecordButtons(boolean focused,
             boolean pressed, boolean invalidate);
     private native void     nativeSelectBestAt(Rect rect);
-    private native void     nativeSetFindIsUp();
+    private native void     nativeSetFindIsEmpty();
+    private native void     nativeSetFindIsUp(boolean isUp);
     private native void     nativeSetFollowedLink(boolean followed);
     private native void     nativeSetHeightCanMeasure(boolean measure);
     private native void     nativeSetRootLayer(int layer);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index da760a1..9e4a16b 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -317,7 +317,7 @@
         List<String> providers = getProviders(enabledOnly);
         for (String providerName : providers) {
             LocationProvider provider = getProvider(providerName);
-            if (provider.meetsCriteria(criteria)) {
+            if (provider != null && provider.meetsCriteria(criteria)) {
                 if (goodProviders.isEmpty()) {
                     goodProviders = new ArrayList<String>();
                 }
diff --git a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp
index 2d05a49..7537e35 100644
--- a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp
+++ b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp
@@ -32,8 +32,7 @@
     }
 
 protected:
-    virtual bool onDecode(SkStream* stream, SkBitmap* bm,
-                          SkBitmap::Config pref, Mode);
+    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
 };
 
 int nullObjectReturn(const char msg[]) {
diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
index f229f9d..209e71c 100644
--- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
+++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp
@@ -97,14 +97,14 @@
 }
 
 bool OmxJpegImageDecoder::onDecode(SkStream* stream,
-        SkBitmap* bm, SkBitmap::Config pref, Mode mode) {
+        SkBitmap* bm, Mode mode) {
     sp<MediaSource> source = prepareMediaSource(stream);
     sp<MetaData> meta = source->getFormat();
     int width;
     int height;
     meta->findInt32(kKeyWidth, &width);
     meta->findInt32(kKeyHeight, &height);
-    configBitmapSize(bm, pref, width, height);
+    configBitmapSize(bm, getPrefConfig(k32Bit_SrcDepth, false), width, height);
 
     // mode == DecodeBounds
     if (mode == SkImageDecoder::kDecodeBounds_Mode) {
diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h
index 7d8bac09c..a313877 100644
--- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h
+++ b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h
@@ -42,8 +42,7 @@
     }
 
 protected:
-    virtual bool onDecode(SkStream* stream, SkBitmap* bm,
-            SkBitmap::Config pref, Mode mode);
+    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode);
 
 private:
     JPEGSource* prepareMediaSource(SkStream* stream);
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 41f3850..3849023 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -523,6 +523,11 @@
 
         Intent in = null;
 
+        if (oldState == VolumeState.Shared && newState != oldState) {
+            mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_UNSHARED,
+                                                Uri.parse("file://" + path)));
+        }
+
         if (newState == VolumeState.Init) {
         } else if (newState == VolumeState.NoMedia) {
             // NoMedia is handled via Disk Remove events
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 6d121c3..53076de 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -447,7 +447,7 @@
             String []tok = line.split(" ");
             int code = Integer.parseInt(tok[0]);
             if (code == NetdResponseCode.UsbRNDISStatusResult) {
-                if (tok[2].equals("started"))
+                if (tok[3].equals("started"))
                     return true;
                 return false;
             } else {
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 9fcb21c..ea021d8 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -637,6 +637,7 @@
         sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
         if (application != NULL) {
             fullyQualifyClassName(origPackage, application, String16("name"));
+            fullyQualifyClassName(origPackage, application, String16("backupAgent"));
 
             Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren());
             for (size_t i = 0; i < children.size(); i++) {
@@ -1778,6 +1779,40 @@
     rules.editValueAt(index).add(where);
 }
 
+void
+addProguardKeepRule(ProguardKeepSet* keep, const String8& inClassName,
+        const char* pkg, const String8& srcName, int line)
+{
+    String8 className(inClassName);
+    if (pkg != NULL) {
+        // asdf     --> package.asdf
+        // .asdf  .a.b  --> package.asdf package.a.b
+        // asdf.adsf --> asdf.asdf
+        const char* p = className.string();
+        const char* q = strchr(p, '.');
+        if (p == q) {
+            className = pkg;
+            className.append(inClassName);
+        } else if (q == NULL) {
+            className = pkg;
+            className.append(".");
+            className.append(inClassName);
+        }
+    }
+    
+    String8 rule("-keep class ");
+    rule += className;
+    rule += " { <init>(...); }";
+
+    String8 location("view ");
+    location += srcName;
+    char lineno[20];
+    sprintf(lineno, ":%d", line);
+    location += lineno;
+
+    keep->add(rule, location);
+}
+
 status_t
 writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& assets)
 {
@@ -1839,6 +1874,13 @@
             if (tag == "application") {
                 inApplication = true;
                 keepTag = true;
+                
+                String8 agent = getAttribute(tree, "http://schemas.android.com/apk/res/android",
+                        "backupAgent", &error);
+                if (agent.length() > 0) {
+                    addProguardKeepRule(keep, agent, pkg.string(),
+                            assFile->getPrintableSource(), tree.getLineNumber());
+                }
             } else if (tag == "instrumentation") {
                 keepTag = true;
             }
@@ -1856,31 +1898,8 @@
                 return -1;
             }
             if (name.length() > 0) {
-                // asdf     --> package.asdf
-                // .asdf  .a.b  --> package.asdf package.a.b
-                // asdf.adsf --> asdf.asdf
-                String8 rule("-keep class ");
-                const char* p = name.string();
-                const char* q = strchr(p, '.');
-                if (p == q) {
-                    rule += pkg;
-                    rule += name;
-                } else if (q == NULL) {
-                    rule += pkg;
-                    rule += ".";
-                    rule += name;
-                } else {
-                    rule += name;
-                }
-
-                String8 location = tag;
-                location += " ";
-                location += assFile->getSourceFile();
-                char lineno[20];
-                sprintf(lineno, ":%d", tree.getLineNumber());
-                location += lineno;
-
-                keep->add(rule, location);
+                addProguardKeepRule(keep, name, pkg.string(),
+                        assFile->getPrintableSource(), tree.getLineNumber());
             }
         }
     }
@@ -1888,23 +1907,6 @@
     return NO_ERROR;
 }
 
-void
-addProguardKeepRule(ProguardKeepSet* keep, const String8& className,
-        const String8& srcName, int line)
-{
-    String8 rule("-keep class ");
-    rule += className;
-    rule += " { <init>(...); }";
-
-    String8 location("view ");
-    location += srcName;
-    char lineno[20];
-    sprintf(lineno, ":%d", line);
-    location += lineno;
-
-    keep->add(rule, location);
-}
-
 status_t
 writeProguardForXml(ProguardKeepSet* keep, const sp<AaptFile>& layoutFile,
         const char* startTag, const char* altTag)
@@ -1946,7 +1948,7 @@
 
         // If there is no '.', we'll assume that it's one of the built in names.
         if (strchr(tag.string(), '.')) {
-            addProguardKeepRule(keep, tag,
+            addProguardKeepRule(keep, tag, NULL,
                     layoutFile->getPrintableSource(), tree.getLineNumber());
         } else if (altTag != NULL && tag == altTag) {
             ssize_t classIndex = tree.indexOfAttribute(NULL, "class");
@@ -1956,7 +1958,7 @@
             } else {
                 size_t len;
                 addProguardKeepRule(keep,
-                        String8(tree.getAttributeStringValue(classIndex, &len)),
+                        String8(tree.getAttributeStringValue(classIndex, &len)), NULL,
                         layoutFile->getPrintableSource(), tree.getLineNumber());
             }
         }