Merge " * Move connectivity manager test closer to source.  * Add license header to java files  * Remove google related information from the test"
diff --git a/api/current.xml b/api/current.xml
index 4af2a43..868f6fc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -193673,6 +193673,17 @@
  visibility="public"
 >
 </method>
+<method name="getPluginState"
+ return="android.webkit.WebSettings.PluginState"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getPluginsEnabled"
  return="boolean"
  abstract="false"
@@ -193680,7 +193691,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -194206,7 +194217,7 @@
 <parameter name="flag" type="boolean">
 </parameter>
 </method>
-<method name="setPluginsEnabled"
+<method name="setPluginState"
  return="void"
  abstract="false"
  native="false"
@@ -194216,6 +194227,19 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="state" type="android.webkit.WebSettings.PluginState">
+</parameter>
+</method>
+<method name="setPluginsEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
 <parameter name="flag" type="boolean">
 </parameter>
 </method>
@@ -194525,6 +194549,39 @@
 >
 </method>
 </class>
+<class name="WebSettings.PluginState"
+ extends="java.lang.Enum"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="valueOf"
+ return="android.webkit.WebSettings.PluginState"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
+<method name="values"
+ return="android.webkit.WebSettings.PluginState[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
 <class name="WebSettings.RenderPriority"
  extends="java.lang.Enum"
  abstract="false"
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 3f0fcb1..6e5b3e1 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -579,10 +579,12 @@
         try {
             // if the cursor hasn't been closed yet, close it first
             if (mWindow != null) {
-                close();
+                int len = mQuery.mSql.length();
                 Log.e(TAG, "Finalizing a Cursor that has not been deactivated or closed. " +
                         "database = " + mDatabase.getPath() + ", table = " + mEditTable +
-                        ", query = " + mQuery.mSql, mStackTrace);
+                        ", query = " + mQuery.mSql.substring(0, (len > 100) ? 100 : len),
+                        mStackTrace);
+                close();
                 SQLiteDebug.notifyActiveCursorFinalized();
             } else {
                 if (Config.LOGV) {
diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java
index fc5c425..23cf6b8 100644
--- a/core/java/android/webkit/ViewManager.java
+++ b/core/java/android/webkit/ViewManager.java
@@ -28,6 +28,7 @@
     private final ArrayList<ChildView> mChildren = new ArrayList<ChildView>();
     private boolean mHidden;
     private boolean mReadyToDraw;
+    private boolean mZoomInProgress = false;
 
     // Threshold at which a surface is prevented from further increasing in size
     private final int MAX_SURFACE_THRESHOLD;
@@ -39,11 +40,6 @@
         int height;
         View mView; // generic view to show
 
-        /* set to true if the view is a surface and it has exceeded the pixel
-           threshold specified in MAX_SURFACE_THRESHOLD.
-         */
-        boolean isFixedSize = false;
-
         ChildView() {
         }
 
@@ -66,19 +62,17 @@
                     // already attached, just set the new LayoutParams,
                     // otherwise attach the view and add it to the list of
                     // children.
-                    AbsoluteLayout.LayoutParams lp = computeLayout(ChildView.this);
+                    requestLayout(ChildView.this);
 
-                    if (mView.getParent() != null) {
-                        mView.setLayoutParams(lp);
-                    } else {
-                        attachViewOnUIThread(lp);
+                    if (mView.getParent() == null) {
+                        attachViewOnUIThread();
                     }
                 }
             });
         }
 
-        private void attachViewOnUIThread(AbsoluteLayout.LayoutParams lp) {
-            mWebView.addView(mView, lp);
+        private void attachViewOnUIThread() {
+            mWebView.addView(mView);
             mChildren.add(this);
             if (!mReadyToDraw) {
                 mView.setVisibility(View.GONE);
@@ -146,35 +140,87 @@
     /**
      * This should only be called from the UI thread.
      */
-    private AbsoluteLayout.LayoutParams computeLayout(ChildView v) {
+    private void requestLayout(ChildView v) {
 
-        // if the surface has exceed a predefined threshold then fix the size
-        // of the surface.
-        if (!v.isFixedSize && (v.width * v.height) > MAX_SURFACE_THRESHOLD
-                && v.mView instanceof SurfaceView) {
-            ((SurfaceView)v.mView).getHolder().setFixedSize(v.width, v.height);
-            v.isFixedSize = true;
-        }
+        int width = ctvD(v.width);
+        int height = ctvD(v.height);
+        int x = ctvX(v.x);
+        int y = ctvY(v.y);
 
         AbsoluteLayout.LayoutParams lp;
         ViewGroup.LayoutParams layoutParams = v.mView.getLayoutParams();
 
         if (layoutParams instanceof AbsoluteLayout.LayoutParams) {
             lp = (AbsoluteLayout.LayoutParams) layoutParams;
-            lp.width = ctvD(v.width);
-            lp.height = ctvD(v.height);
-            lp.x = ctvX(v.x);
-            lp.y = ctvY(v.y);
+            lp.width = width;
+            lp.height = height;
+            lp.x = x;
+            lp.y = y;
         } else {
-            lp = new AbsoluteLayout.LayoutParams(ctvD(v.width), ctvD(v.height),
-                    ctvX(v.x), ctvY(v.y));
+            lp = new AbsoluteLayout.LayoutParams(width, height, x, y);
         }
-        return lp;
+
+        // apply the layout to the view
+        v.mView.setLayoutParams(lp);
+
+        if(v.mView instanceof SurfaceView) {
+
+            final SurfaceView sView = (SurfaceView) v.mView;
+            boolean exceedThreshold = (width * height) > MAX_SURFACE_THRESHOLD;
+
+            /* If the surface has exceeded a predefined threshold or the webview
+             * is currently zoom then fix the size of the surface.
+             *
+             * NOTE: plugins (e.g. Flash) must not explicitly fix the size of
+             * their surface. The logic below will result in unexpected behavior
+             * for the plugin if they attempt to fix the size of the surface.
+             */
+            if (!sView.isFixedSize() && (exceedThreshold || mZoomInProgress)) {
+                sView.getHolder().setFixedSize(width, height);
+            }
+            else if (sView.isFixedSize() && !exceedThreshold && !mZoomInProgress) {
+                /* The changing of visibility is a hack to get around a bug in
+                 * the framework that causes the surface to revert to the size
+                 * it was prior to being fixed before it redraws using the
+                 * values currently in its layout.
+                 *
+                 * The surface is destroyed when it is set to invisible and then
+                 * recreated at the new dimensions when it is made visible. The
+                 * same destroy/create step occurs without the change in
+                 * visibility, but then exhibits the behavior described in the
+                 * previous paragraph.
+                 */
+                if (sView.getVisibility() == View.VISIBLE) {
+                    sView.setVisibility(View.INVISIBLE);
+                    sView.getHolder().setSizeFromLayout();
+                    sView.setVisibility(View.VISIBLE);
+                } else {
+                    sView.getHolder().setSizeFromLayout();
+                }
+            }
+            else if (sView.isFixedSize() && exceedThreshold) {
+                sView.requestLayout();
+            }
+        }
+    }
+
+    void startZoom() {
+        mZoomInProgress = true;
+        for (ChildView v : mChildren) {
+            requestLayout(v);
+        }
+    }
+
+    void endZoom() {
+        mZoomInProgress = false;
+        for (ChildView v : mChildren) {
+            requestLayout(v);
+        }
     }
 
     void scaleAll() {
         for (ChildView v : mChildren) {
-            v.mView.setLayoutParams(computeLayout(v));
+            requestLayout(v);
         }
     }
 
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index d1da5ea..1b801d4 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -120,6 +120,21 @@
         LOW
     }
 
+    /**
+     * The plugin state effects how plugins are treated on a page. ON means
+     * that any object will be loaded even if a plugin does not exist to handle
+     * the content. ON_DEMAND means that if there is a plugin installed that
+     * can handle the content, a placeholder is shown until the user clicks on
+     * the placeholder. Once clicked, the plugin will be enabled on the page.
+     * OFF means that all plugins will be turned off and any fallback content
+     * will be used.
+     */
+    public enum PluginState {
+        ON,
+        ON_DEMAND,
+        OFF
+    }
+
     // WebView associated with this WebSettings.
     private WebView mWebView;
     // BrowserFrame used to access the native frame pointer.
@@ -157,7 +172,7 @@
     private boolean         mBlockNetworkImage = false;
     private boolean         mBlockNetworkLoads;
     private boolean         mJavaScriptEnabled = false;
-    private boolean         mPluginsEnabled = false;
+    private PluginState     mPluginState = PluginState.OFF;
     private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
     private boolean         mUseDoubleTree = false;
     private boolean         mUseWideViewport = false;
@@ -1011,10 +1026,23 @@
     /**
      * Tell the WebView to enable plugins.
      * @param flag True if the WebView should load plugins.
+     * @deprecated This method has been deprecated in favor of
+     *             {@link #setPluginState}
      */
     public synchronized void setPluginsEnabled(boolean flag) {
-        if (mPluginsEnabled != flag) {
-            mPluginsEnabled = flag;
+        setPluginState(PluginState.ON);
+    }
+
+    /**
+     * Tell the WebView to enable, disable, or have plugins on demand. On
+     * demand mode means that if a plugin exists that can handle the embedded
+     * content, a placeholder icon will be shown instead of the plugin. When
+     * the placeholder is clicked, the plugin will be enabled.
+     * @param state One of the PluginState values.
+     */
+    public synchronized void setPluginState(PluginState state) {
+        if (mPluginState != state) {
+            mPluginState = state;
             postSync();
         }
     }
@@ -1176,9 +1204,18 @@
     /**
      * Return true if plugins are enabled.
      * @return True if plugins are enabled.
+     * @deprecated This method has been replaced by {@link #getPluginState}
      */
     public synchronized boolean getPluginsEnabled() {
-        return mPluginsEnabled;
+        return mPluginState == PluginState.ON;
+    }
+
+    /**
+     * Return the current plugin state.
+     * @return A value corresponding to the enum PluginState.
+     */
+    public synchronized PluginState getPluginState() {
+        return mPluginState;
     }
 
     /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 784f886..f886eef 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4460,6 +4460,9 @@
             if (inEditingMode() && nativeFocusCandidateIsPassword()) {
                 mWebTextView.setInPassword(false);
             }
+
+            mViewManager.startZoom();
+
             return true;
         }
 
@@ -4493,6 +4496,8 @@
             mConfirmMove = true;
             startTouch(detector.getFocusX(), detector.getFocusY(),
                     mLastTouchTime);
+
+            mViewManager.endZoom();
         }
 
         public boolean onScale(ScaleGestureDetector detector) {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index eb2da71..e15a520 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -92,6 +92,13 @@
 
     private static final int HINT_VIEW_ID = 0x17;
 
+    /**
+     * This value controls the length of time that the user
+     * must leave a pointer down without scrolling to expand
+     * the autocomplete dropdown list to cover the IME.
+     */
+    private static final int EXPAND_LIST_TIMEOUT = 250;
+
     private CharSequence mHintText;
     private int mHintResource;
 
@@ -132,6 +139,7 @@
 
     private ListSelectorHider mHideSelector;
     private Runnable mShowDropDownRunnable;
+    private Runnable mResizePopupRunnable = new ResizePopupRunnable();
 
     private PassThroughClickListener mPassThroughClickListener;
     private PopupDataSetObserver mObserver;
@@ -1297,6 +1305,7 @@
                 public void onNothingSelected(AdapterView<?> parent) {
                 }
             });
+            mDropDownList.setOnScrollListener(new PopupScrollListener());
 
             if (mItemSelectedListener != null) {
                 mDropDownList.setOnItemSelectedListener(mItemSelectedListener);
@@ -1437,17 +1446,41 @@
         }
     }
 
+    private class ResizePopupRunnable implements Runnable {
+        public void run() {
+            mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+            showDropDown();
+        }
+    }
+
     private class PopupTouchInterceptor implements OnTouchListener {
         public boolean onTouch(View v, MotionEvent event) {
-            if (event.getAction() == MotionEvent.ACTION_DOWN &&
+            final int action = event.getAction();
+            if (action == MotionEvent.ACTION_DOWN &&
                     mPopup != null && mPopup.isShowing()) {
-                mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
-                showDropDown();
+                postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT);
+            } else if (action == MotionEvent.ACTION_UP) {
+                removeCallbacks(mResizePopupRunnable);
             }
             return false;
         }
     }
     
+    private class PopupScrollListener implements ListView.OnScrollListener {
+        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+                int totalItemCount) {
+
+        }
+
+        public void onScrollStateChanged(AbsListView view, int scrollState) {
+            if (scrollState == SCROLL_STATE_TOUCH_SCROLL &&
+                    !isInputMethodNotNeeded() && mPopup.getContentView() != null) {
+                removeCallbacks(mResizePopupRunnable);
+                mResizePopupRunnable.run();
+            }
+        }
+    }
+
     private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
         public void onItemClick(AdapterView parent, View v, int position, long id) {
             performCompletion(v, position, id);
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 239c5f4..f009432 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -573,6 +573,7 @@
         } else {
             super.scrollTo(scrollX, scrollY);
         }
+        awakenScrollBars();
     }
     
     private int getOverscrollMax() {
@@ -1297,7 +1298,6 @@
                 mScrollViewMovedFocus = false;
             }
     
-            awakenScrollBars(mScroller.getDuration());
             invalidate();
         }
     }
diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java
index 479965a..4b17a92 100644
--- a/core/java/android/widget/SimpleAdapter.java
+++ b/core/java/android/widget/SimpleAdapter.java
@@ -172,6 +172,10 @@
                     if (v instanceof Checkable) {
                         if (data instanceof Boolean) {
                             ((Checkable) v).setChecked((Boolean) data);
+                        } else if (v instanceof TextView) {
+                            // Note: keep the instanceof TextView check at the bottom of these
+                            // ifs since a lot of views are TextViews (e.g. CheckBoxes).
+                            setViewText((TextView) v, text);
                         } else {
                             throw new IllegalStateException(v.getClass().getName() +
                                     " should be bound to a Boolean, not a " +
diff --git a/core/res/assets/webkit/togglePlugin.png b/core/res/assets/webkit/togglePlugin.png
new file mode 100644
index 0000000..008333c
--- /dev/null
+++ b/core/res/assets/webkit/togglePlugin.png
Binary files differ
diff --git a/core/res/assets/webkit/togglePluginBg.png b/core/res/assets/webkit/togglePluginBg.png
new file mode 100644
index 0000000..2c65acb
--- /dev/null
+++ b/core/res/assets/webkit/togglePluginBg.png
Binary files differ
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 164df72..407fd57 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1153,6 +1153,8 @@
             Mutex::Autolock autoLock(mLock);
             if (mFlags & PREPARE_CANCELLED) {
                 LOGI("prepare was cancelled before preparing the prefetcher");
+
+                prefetcher.clear();
                 abortPrepare(UNKNOWN_ERROR);
                 return;
             }
diff --git a/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml b/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml
index 5564300..3b8b3b1 100644
--- a/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml
+++ b/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml
@@ -2,4 +2,5 @@
 
 <!-- Just need this dummy file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="dummy">dummy</string>
 </resources>
diff --git a/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml b/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml
index 5564300..3b8b3b1 100644
--- a/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml
+++ b/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml
@@ -2,4 +2,5 @@
 
 <!-- Just need this dummy file to have something to build. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string name="dummy">dummy</string>
 </resources>