Merge "Make fragment host usable"
diff --git a/v4/api/current.txt b/v4/api/current.txt
index ab6ed35..95db435 100644
--- a/v4/api/current.txt
+++ b/v4/api/current.txt
@@ -114,10 +114,11 @@
     method public boolean getAllowReturnTransitionOverlap();
     method public final android.os.Bundle getArguments();
     method public final android.support.v4.app.FragmentManager getChildFragmentManager();
-    method public final android.content.Context getContext();
+    method public android.content.Context getContext();
     method public java.lang.Object getEnterTransition();
     method public java.lang.Object getExitTransition();
     method public final android.support.v4.app.FragmentManager getFragmentManager();
+    method public final java.lang.Object getHost();
     method public final int getId();
     method public android.support.v4.app.LoaderManager getLoaderManager();
     method public final android.support.v4.app.Fragment getParentFragment();
@@ -233,7 +234,7 @@
 
   public class FragmentController {
     method public void attachHost(android.support.v4.app.Fragment);
-    method public static final android.support.v4.app.FragmentController createController(android.support.v4.app.FragmentHostCallbacks);
+    method public static final android.support.v4.app.FragmentController createController(android.support.v4.app.FragmentHostCallbacks<?>);
     method public void dispatchActivityCreated();
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
     method public boolean dispatchContextItemSelected(android.view.MenuItem);
@@ -250,6 +251,10 @@
     method public void dispatchResume();
     method public void dispatchStart();
     method public void dispatchStop();
+    method public void doLoaderDestroy();
+    method public void doLoaderRetain();
+    method public void doLoaderStart();
+    method public void doLoaderStop(boolean);
     method public void dumpLoaders(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public boolean execPendingActions();
     method public java.util.List<android.support.v4.app.Fragment> getActiveFragments(java.util.List<android.support.v4.app.Fragment>);
@@ -258,6 +263,7 @@
     method public android.support.v4.app.LoaderManager getSupportLoaderManager();
     method public void noteStateNotSaved();
     method public android.view.View onCreateView(android.view.View, java.lang.String, android.content.Context, android.util.AttributeSet);
+    method public void reportLoaderStart();
     method public void restoreAllState(android.os.Parcelable, java.util.ArrayList<android.support.v4.app.Fragment>);
     method public void restoreLoaderNonConfig(android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager>);
     method public android.support.v4.util.SimpleArrayMap<java.lang.String, android.support.v4.app.LoaderManager> retainLoaderNonConfig();
@@ -269,6 +275,7 @@
     ctor public FragmentHostCallbacks(android.content.Context, android.os.Handler, int);
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public android.view.View findViewById(int);
+    method public E getHost();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getWindowAnimations();
     method public boolean hasView();
diff --git a/v4/java/android/support/v4/app/Fragment.java b/v4/java/android/support/v4/app/Fragment.java
index 2187777..1913cae 100644
--- a/v4/java/android/support/v4/app/Fragment.java
+++ b/v4/java/android/support/v4/app/Fragment.java
@@ -609,7 +609,7 @@
     /**
      * Return the {@link Context} this fragment is currently associated with.
      */
-    final public Context getContext() {
+    public Context getContext() {
         return mHost == null ? null : mHost.getContext();
     }
 
@@ -623,6 +623,14 @@
     }
 
     /**
+     * Return the host object of this fragment. May return {@code null} if the fragment
+     * isn't currently being hosted.
+     */
+    final public Object getHost() {
+        return mHost == null ? null : mHost.getHost();
+    }
+
+    /**
      * Return <code>getActivity().getResources()</code>.
      */
     final public Resources getResources() {
diff --git a/v4/java/android/support/v4/app/FragmentActivity.java b/v4/java/android/support/v4/app/FragmentActivity.java
index ebb1c64..2bf3189 100644
--- a/v4/java/android/support/v4/app/FragmentActivity.java
+++ b/v4/java/android/support/v4/app/FragmentActivity.java
@@ -768,7 +768,7 @@
         super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));
     }
 
-    class HostCallbacks extends FragmentHostCallbacks {
+    class HostCallbacks extends FragmentHostCallbacks<FragmentActivity> {
         public HostCallbacks() {
             super(FragmentActivity.this /*fragmentActivity*/);
         }
@@ -789,6 +789,11 @@
         }
 
         @Override
+        public FragmentActivity getHost() {
+            return FragmentActivity.this;
+        }
+
+        @Override
         public void supportInvalidateOptionsMenu() {
             FragmentActivity.this.supportInvalidateOptionsMenu();
         }
diff --git a/v4/java/android/support/v4/app/FragmentController.java b/v4/java/android/support/v4/app/FragmentController.java
index bd2da21..2651aff 100644
--- a/v4/java/android/support/v4/app/FragmentController.java
+++ b/v4/java/android/support/v4/app/FragmentController.java
@@ -37,16 +37,16 @@
  * the {@link Fragment} lifecycle.
  */
 public class FragmentController {
-    private final FragmentHostCallbacks mHost;
+    private final FragmentHostCallbacks<?> mHost;
 
     /**
      * Returns a {@link FragmentController}.
      */
-    public static final FragmentController createController(FragmentHostCallbacks callbacks) {
+    public static final FragmentController createController(FragmentHostCallbacks<?> callbacks) {
         return new FragmentController(callbacks);
     }
 
-    private FragmentController(FragmentHostCallbacks callbacks) {
+    private FragmentController(FragmentHostCallbacks<?> callbacks) {
         mHost = callbacks;
     }
 
@@ -186,7 +186,10 @@
         return mHost.mFragmentManager.execPendingActions();
     }
 
-    void doLoaderStart() {
+    /**
+     * Starts the loaders.
+     */
+    public void doLoaderStart() {
         mHost.doLoaderStart();
     }
 
@@ -197,19 +200,29 @@
      * @param retain When {@code true}, the loaders aren't stopped, but, their instances
      * are retained in a started state
      */
-    void doLoaderStop(boolean retain) {
+    public void doLoaderStop(boolean retain) {
         mHost.doLoaderStop(retain);
     }
 
-    void doLoaderRetain() {
+    /**
+     * Retains the state of each of the loaders.
+     */
+    public void doLoaderRetain() {
         mHost.doLoaderRetain();
     }
 
-    void doLoaderDestroy() {
+    /**
+     * Destroys all inactive loaders and optionally destroys all active loaders. Active loaders
+     * will not be destroyed if their state is retained.
+     */
+    public void doLoaderDestroy() {
         mHost.doLoaderDestroy();
     }
 
-    void reportLoaderStart() {
+    /**
+     * Reports all loaders as started.
+     */
+    public void reportLoaderStart() {
         mHost.reportLoaderStart();
     }
 
diff --git a/v4/java/android/support/v4/app/FragmentHostCallbacks.java b/v4/java/android/support/v4/app/FragmentHostCallbacks.java
index 9b42a96..d304f3a 100644
--- a/v4/java/android/support/v4/app/FragmentHostCallbacks.java
+++ b/v4/java/android/support/v4/app/FragmentHostCallbacks.java
@@ -33,7 +33,7 @@
 /**
  * Provides integration points with the host that is managing the {@link Fragment} lifecycle.
  */
-public class FragmentHostCallbacks extends FragmentContainer {
+public class FragmentHostCallbacks<E> extends FragmentContainer {
     private final Activity mActivity;
     final Context mContext;
     private final Handler mHandler;
@@ -88,6 +88,16 @@
     }
 
     /**
+     * Return the object that's currently hosting the fragment. If a {@link Fragment}
+     * is hosted by a {@link FragmentActivity}, the object returned here should be
+     * the same object returned from {@link Fragment#getActivity()}.
+     */
+    @Nullable
+    public E getHost() {
+        return null;
+    }
+
+    /**
      * Invalidates the activity's options menu.
      * See {@link FragmentActivity#supportInvalidateOptionsMenu()}
      */