Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9bab98d authored by Adam Powell's avatar Adam Powell
Browse files

Move child FragmentManager shutdown for retained fragments

Some apps out there do some creative things in terms of calling their
own onDetach methods from elsewhere. Perform the child FragmentManager
shutdown for retained fragments in a package-level perform method
instead of in onDetach itself.

Also mark all existing fragment methods with @CallSuper.

Bug 28293847

Change-Id: I343b610f8d427fe5cabd523a78fbf0e6f3b34c57
parent 54a6394c
Loading
Loading
Loading
Loading
+40 −12
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;

import android.animation.Animator;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
@@ -1335,6 +1336,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
     */
    @Deprecated
    @CallSuper
    public void onInflate(AttributeSet attrs, Bundle savedInstanceState) {
        mCalled = true;
    }
@@ -1381,6 +1383,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    @CallSuper
    public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
        onInflate(attrs, savedInstanceState);
        mCalled = true;
@@ -1421,6 +1424,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @deprecated Use {@link #onInflate(Context, AttributeSet, Bundle)} instead.
     */
    @Deprecated
    @CallSuper
    public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
        mCalled = true;
    }
@@ -1429,6 +1433,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * Called when a fragment is first attached to its context.
     * {@link #onCreate(Bundle)} will be called after this.
     */
    @CallSuper
    public void onAttach(Context context) {
        mCalled = true;
        final Activity hostActivity = mHost == null ? null : mHost.getActivity();
@@ -1442,6 +1447,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @deprecated Use {@link #onAttach(Context)} instead.
     */
    @Deprecated
    @CallSuper
    public void onAttach(Activity activity) {
        mCalled = true;
    }
@@ -1473,6 +1479,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    @CallSuper
    public void onCreate(@Nullable Bundle savedInstanceState) {
        mCalled = true;
        final Context context = getContext();
@@ -1558,6 +1565,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    @CallSuper
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        mCalled = true;
    }
@@ -1573,6 +1581,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    @CallSuper
    public void onViewStateRestored(Bundle savedInstanceState) {
        mCalled = true;
    }
@@ -1582,6 +1591,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * tied to {@link Activity#onStart() Activity.onStart} of the containing
     * Activity's lifecycle.
     */
    @CallSuper
    public void onStart() {
        mCalled = true;

@@ -1603,6 +1613,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * tied to {@link Activity#onResume() Activity.onResume} of the containing
     * Activity's lifecycle.
     */
    @CallSuper
    public void onResume() {
        mCalled = true;
    }
@@ -1648,6 +1659,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
    }

    @CallSuper
    public void onConfigurationChanged(Configuration newConfig) {
        mCalled = true;
    }
@@ -1657,6 +1669,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * tied to {@link Activity#onPause() Activity.onPause} of the containing
     * Activity's lifecycle.
     */
    @CallSuper
    public void onPause() {
        mCalled = true;
    }
@@ -1666,14 +1679,17 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * tied to {@link Activity#onStop() Activity.onStop} of the containing
     * Activity's lifecycle.
     */
    @CallSuper
    public void onStop() {
        mCalled = true;
    }

    @CallSuper
    public void onLowMemory() {
        mCalled = true;
    }

    @CallSuper
    public void onTrimMemory(int level) {
        mCalled = true;
    }
@@ -1687,6 +1703,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * non-null view.  Internally it is called after the view's state has
     * been saved but before it has been removed from its parent.
     */
    @CallSuper
    public void onDestroyView() {
        mCalled = true;
    }
@@ -1695,6 +1712,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * Called when the fragment is no longer in use.  This is called
     * after {@link #onStop()} and before {@link #onDetach()}.
     */
    @CallSuper
    public void onDestroy() {
        mCalled = true;
        //Log.v("foo", "onDestroy: mCheckedForLoaderManager=" + mCheckedForLoaderManager
@@ -1743,20 +1761,9 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
     * Activity re-creation (see {@link #setRetainInstance(boolean)}), in which case it is called
     * after {@link #onStop()}.
     */
    @CallSuper
    public void onDetach() {
        mCalled = true;

        // Destroy the child FragmentManager if we still have it here.
        // We won't unless we're retaining our instance and if we do,
        // our child FragmentManager instance state will have already been saved.
        if (mChildFragmentManager != null) {
            if (!mRetaining) {
                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
                        + " destroyed and this fragment is not retaining instance");
            }
            mChildFragmentManager.dispatchDestroy();
            mChildFragmentManager = null;
        }
    }

    /**
@@ -2568,6 +2575,27 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
        mChildFragmentManager = null;
    }

    void performDetach() {
        mCalled = false;
        onDetach();
        if (!mCalled) {
            throw new SuperNotCalledException("Fragment " + this
                    + " did not call through to super.onDetach()");
        }

        // Destroy the child FragmentManager if we still have it here.
        // We won't unless we're retaining our instance and if we do,
        // our child FragmentManager instance state will have already been saved.
        if (mChildFragmentManager != null) {
            if (!mRetaining) {
                throw new IllegalStateException("Child FragmentManager of " + this + " was not "
                        + " destroyed and this fragment is not retaining instance");
            }
            mChildFragmentManager.dispatchDestroy();
            mChildFragmentManager = null;
        }
    }

    private static Transition loadTransition(Context context, TypedArray typedArray,
            Transition currentValue, Transition defaultValue, int id) {
        if (currentValue != defaultValue) {
+1 −6
Original line number Diff line number Diff line
@@ -1117,12 +1117,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
                                f.mState = Fragment.INITIALIZING;
                            }

                            f.mCalled = false;
                            f.onDetach();
                            if (!f.mCalled) {
                                throw new SuperNotCalledException("Fragment " + f
                                        + " did not call through to super.onDetach()");
                            }
                            f.performDetach();
                            if (!keepActive) {
                                if (!f.mRetaining) {
                                    makeInactive(f);