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

Commit ce418e66 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #3495749: Crash on choosing to open the downloaded images

This is due to the window doing a relayout after its activity is
stopped, at which point it may need to interact with the adapter
to load data.

The fix here is to tell ViewRoot about an activity being stopped
and, if in this state, hold off on doing any new measurements and
layouts of the hierarchy until it is no longer stopped.

In this case the relayout was happening due to the cursor
being deactivated, with causes the adapter to invalidate
its data.  Because this is now in a dialog window, this
allows the window to actually be resized smaller (unlike when
in a full screen activity), and boom.

Change-Id: I26442b4679819b4a4e6bc56289afd3445526750b
parent 6c2193a7
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManagerImpl;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
@@ -4401,6 +4402,9 @@ public class Activity extends ContextThemeWrapper
        if (mStopped) {
            mStopped = false;
            mCalled = false;
            if (mToken != null && mParent == null) {
                WindowManagerImpl.getDefault().setStoppedState(mToken, false);
            }
            mInstrumentation.callActivityOnRestart(this);
            if (!mCalled) {
                throw new SuperNotCalledException(
@@ -4477,6 +4481,10 @@ public class Activity extends ContextThemeWrapper
                mWindow.closeAllPanels();
            }

            if (mToken != null && mParent == null) {
                WindowManagerImpl.getDefault().setStoppedState(mToken, true);
            }
            
            mFragments.dispatchStop();
            
            mCalled = false;
+59 −44
Original line number Diff line number Diff line
@@ -155,6 +155,10 @@ public final class ViewRoot extends Handler implements ViewParent,
    int mViewVisibility;
    boolean mAppVisible = true;

    // Set to true if the owner of this window is in the stopped state,
    // so the window should no longer be active.
    boolean mStopped = false;
    
    SurfaceHolder.Callback2 mSurfaceHolderCallback;
    BaseSurfaceHolder mSurfaceHolder;
    boolean mIsCreating;
@@ -618,6 +622,15 @@ public final class ViewRoot extends Handler implements ViewParent,
        scheduleTraversals();
    }

    void setStopped(boolean stopped) {
        if (mStopped != stopped) {
            mStopped = stopped;
            if (!stopped) {
                scheduleTraversals();
            }
        }
    }
    
    public ViewParent getParent() {
        return null;
    }
@@ -760,7 +773,7 @@ public final class ViewRoot extends Handler implements ViewParent,

        boolean insetsChanged = false;

        if (mLayoutRequested) {
        if (mLayoutRequested && !mStopped) {
            // Execute enqueued actions on every layout in case a view that was detached
            // enqueued an action after being detached
            getRunQueue().executeActions(attachInfo.mHandler);
@@ -1143,6 +1156,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
            }

            if (!mStopped) {
                boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
                        (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
                if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
@@ -1189,8 +1203,9 @@ public final class ViewRoot extends Handler implements ViewParent,
                    mLayoutRequested = true;
                }
            }
        }

        final boolean didLayout = mLayoutRequested;
        final boolean didLayout = mLayoutRequested && !mStopped;
        boolean triggerGlobalLayoutListener = didLayout
                || attachInfo.mRecomputeGlobalAttributes;
        if (didLayout) {
+14 −0
Original line number Diff line number Diff line
@@ -302,6 +302,20 @@ public class WindowManagerImpl implements WindowManager {
        }
    }
    
    public void setStoppedState(IBinder token, boolean stopped) {
        synchronized (this) {
            if (mViews == null)
                return;
            int count = mViews.length;
            for (int i=0; i<count; i++) {
                if (token == null || mParams[i].token == token) {
                    ViewRoot root = mRoots[i];
                    root.setStopped(stopped);
                }
            }
        }
    }
    
    public WindowManager.LayoutParams getRootViewLayoutParameter(View view) {
        ViewParent vp = view.getParent();
        while (vp != null && !(vp instanceof ViewRoot)) {