Fixing memory leak in QSB widget

> Instead of recreating the whole fragment, only recreating the views
when reinflating
> Binding the fragment in xml instead of in code

This prevents duplicate fragment binding

Bug: 29120662
Change-Id: I25b942f64d68f25e1358f15d8a919daeebdcff9c
diff --git a/res/layout/qsb_container.xml b/res/layout/qsb_container.xml
index 3de2876..55c7390 100644
--- a/res/layout/qsb_container.xml
+++ b/res/layout/qsb_container.xml
@@ -20,4 +20,11 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/qsb_container"
-        android:padding="0dp" />
\ No newline at end of file
+        android:padding="0dp" >
+
+    <fragment
+        android:name="com.android.launcher3.QsbContainerView$QsbFragment"
+        android:layout_width="match_parent"
+        android:tag="qsb_view"
+        android:layout_height="match_parent"/>
+</com.android.launcher3.QsbContainerView>
\ No newline at end of file
diff --git a/src/com/android/launcher3/QsbContainerView.java b/src/com/android/launcher3/QsbContainerView.java
index 0a112d2..f931aba 100644
--- a/src/com/android/launcher3/QsbContainerView.java
+++ b/src/com/android/launcher3/QsbContainerView.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.app.Fragment;
-import android.app.FragmentManager;
 import android.app.SearchManager;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
@@ -44,8 +43,6 @@
  */
 public class QsbContainerView extends FrameLayout {
 
-    private boolean mBound;
-
     public QsbContainerView(Context context) {
         super(context);
     }
@@ -59,17 +56,6 @@
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        if (!mBound) {
-            FragmentManager fm = ((Launcher) getContext()).getFragmentManager();
-            fm.beginTransaction().add(R.id.qsb_container, new QsbFragment()).commit();
-            mBound = true;
-        }
-    }
-
-    @Override
     public void setPadding(int left, int top, int right, int bottom) {
         super.setPadding(0, 0, 0, 0);
     }
@@ -103,6 +89,8 @@
             getContext().registerReceiver(mRebindReceiver, filter);
         }
 
+        private FrameLayout mWrapper;
+
         @Override
         public View onCreateView(
                 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -110,7 +98,12 @@
             if (savedInstanceState != null) {
                 sSavedWidgetId = savedInstanceState.getInt(QSB_WIDGET_ID, -1);
             }
+            mWrapper = new FrameLayout(getContext());
+            mWrapper.addView(createQsb(inflater, mWrapper));
+            return mWrapper;
+        }
 
+        private View createQsb(LayoutInflater inflater, ViewGroup container) {
             Launcher launcher = (Launcher) getActivity();
             mWidgetInfo = getSearchWidgetProvider(launcher);
             if (mWidgetInfo == null) {
@@ -222,10 +215,9 @@
         }
 
         private void rebindFragment() {
-            if (getActivity() != null) {
-                // Recreate the fragment. This will cause the qsb to be inflated again.
-                getActivity().getFragmentManager().beginTransaction()
-                        .replace(R.id.qsb_container, new QsbFragment()).commit();
+            if (mWrapper != null && getActivity() != null) {
+                mWrapper.removeAllViews();
+                mWrapper.addView(createQsb(getActivity().getLayoutInflater(), mWrapper));
             }
         }